Freeciv-3.2: /fast/freeciv/nightly/S3_2/client/control.c Source File

Freeciv-3.2

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 do_unit_teleport_to(struct unit *punit, struct tile *ptile);
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,
374 IDENTITY_NUMBER_ZERO,
375 tile_index(punit->action_decision_tile),
376 EXTRA_NONE,
377 REQEST_PLAYER_INITIATED);
378}
379
380/**********************************************************************/
383 bool unit_is_in_focus(const struct unit *punit)
384{
385 return unit_list_search(get_units_in_focus(), punit) != NULL;
386}
387
388/**********************************************************************/
391 struct unit *get_focus_unit_on_tile(const struct tile *ptile)
392{
393 unit_list_iterate(get_units_in_focus(), punit) {
394 if (unit_tile(punit) == ptile) {
395 return punit;
396 }
397 } unit_list_iterate_end;
398
399 return NULL;
400}
401
402/**********************************************************************/
405 struct unit *head_of_units_in_focus(void)
406{
407 return unit_list_get(current_focus, 0);
408}
409
410/**********************************************************************/
413 static struct tile *find_a_focus_unit_tile_to_center_on(void)
414{
415 struct unit *punit;
416
417 if (NULL != (punit = get_focus_unit_on_tile(get_center_tile_mapcanvas()))) {
418 return unit_tile(punit);
419 } else if (get_num_units_in_focus() > 0) {
420 return unit_tile(head_of_units_in_focus());
421 } else {
422 return NULL;
423 }
424}
425
426/**********************************************************************/
429 void auto_center_on_focus_unit(void)
430{
431 struct tile *ptile = find_a_focus_unit_tile_to_center_on();
432
433 if (ptile && gui_options.auto_center_on_unit
434 && !tile_visible_and_not_on_border_mapcanvas(ptile)) {
435 center_tile_mapcanvas(ptile);
436 }
437}
438
439/**********************************************************************/
442 static void current_focus_append(struct unit *punit)
443{
444 unit_list_append(current_focus, punit);
445
446 punit->client.focus_status = FOCUS_AVAIL;
447 refresh_unit_mapcanvas(punit, unit_tile(punit), TRUE, FALSE);
448
449 if (should_ask_server_for_actions(punit)
450 && can_ask_server_for_actions()) {
451 ask_server_for_actions(punit);
452 }
453
454 if (gui_options.unit_selection_clears_orders) {
455 clear_unit_orders(punit);
456 }
457}
458
459/**********************************************************************/
462 static void current_focus_remove(struct unit *punit)
463{
464 /* Close the action selection dialog if the actor unit lose focus. */
465 if (action_selection_actor_unit() == punit->id) {
466 action_selection_close();
467 }
468
469 unit_list_remove(current_focus, punit);
470 refresh_unit_mapcanvas(punit, unit_tile(punit), TRUE, FALSE);
471}
472
473/**********************************************************************/
476 void clear_unit_orders(struct unit *punit)
477{
478 if (!punit) {
479 return;
480 }
481
482 if (punit->activity != ACTIVITY_IDLE
483 || punit->ssa_controller != SSA_NONE) {
484 punit->ssa_controller = SSA_NONE;
485 refresh_unit_city_dialogs(punit);
486 request_new_unit_activity(punit, ACTIVITY_IDLE);
487 } else if (unit_has_orders(punit)) {
488 /* Clear the focus unit's orders. */
489 request_orders_cleared(punit);
490 }
491}
492
493/**********************************************************************/
501 void unit_focus_set(struct unit *punit)
502{
503 bool focus_changed = FALSE;
504
505 if (NULL != punit
506 && NULL != client.conn.playing
507 && unit_owner(punit) != client.conn.playing) {
508 /* Callers should make sure this never happens. */
509 return;
510 }
511
512 /* FIXME: this won't work quite right; for instance activating a
513 * battlegroup twice in a row will store the focus erronously. The only
514 * solution would be a set_units_focus() */
515 if (!(get_num_units_in_focus() == 1
516 && punit == head_of_units_in_focus())) {
517 store_previous_focus();
518 focus_changed = TRUE;
519 }
520
521 /* Close the action selection dialog if the actor unit lose focus. */
522 unit_list_iterate(current_focus, punit_old) {
523 if (action_selection_actor_unit() == punit_old->id) {
524 action_selection_close();
525 }
526 } unit_list_iterate_end;
527
528 /* Redraw the old focus unit (to fix blinking or remove the selection
529 * circle). */
530 unit_list_iterate(current_focus, punit_old) {
531 refresh_unit_mapcanvas(punit_old, unit_tile(punit_old), TRUE, FALSE);
532 } unit_list_iterate_end;
533 unit_list_clear(current_focus);
534
535 if (!can_client_change_view()) {
536 /* This function can be called to set the focus to NULL when
537 * disconnecting. In this case we don't want any other actions! */
538 fc_assert(punit == NULL);
539 return;
540 }
541
542 if (NULL != punit) {
543 current_focus_append(punit);
544 auto_center_on_focus_unit();
545 }
546
547 if (focus_changed) {
548 clear_hover_state();
549 focus_units_changed();
550 }
551}
552
553/**********************************************************************/
556 void unit_focus_add(struct unit *punit)
557{
558 if (NULL != punit
559 && NULL != client.conn.playing
560 && unit_owner(punit) != client.conn.playing) {
561 /* Callers should make sure this never happens. */
562 return;
563 }
564
565 if (NULL == punit || !can_client_change_view()) {
566 return;
567 }
568
569 if (unit_is_in_focus(punit)) {
570 return;
571 }
572
573 if (hover_state != HOVER_NONE) {
574 /* Can't continue with current goto if set of focus units
575 * change. Cancel it. */
576 clear_hover_state();
577 }
578
579 current_focus_append(punit);
580 focus_units_changed();
581}
582
583/**********************************************************************/
586 void unit_focus_remove(struct unit *punit)
587{
588 if (NULL != punit
589 && NULL != client.conn.playing
590 && unit_owner(punit) != client.conn.playing) {
591 /* Callers should make sure this never happens. */
592 return;
593 }
594
595 if (NULL == punit || !can_client_change_view()) {
596 return;
597 }
598
599 if (!unit_is_in_focus(punit)) {
600 return;
601 }
602
603 if (hover_state != HOVER_NONE) {
604 /* Can't continue with current goto if set of focus units
605 * change. Cancel it. */
606 clear_hover_state();
607 }
608
609 current_focus_remove(punit);
610 if (get_num_units_in_focus() > 0) {
611 focus_units_changed();
612 } else {
613 unit_focus_advance();
614 }
615}
616
617/**********************************************************************/
620 void unit_focus_set_and_select(struct unit *punit)
621{
622 unit_focus_set(punit);
623 if (punit) {
624 put_cross_overlay_tile(unit_tile(punit));
625 }
626}
627
628/**********************************************************************/
633 static struct unit *find_best_focus_candidate(bool accept_current)
634{
635 struct tile *ptile = get_center_tile_mapcanvas();
636
637 if (!get_focus_unit_on_tile(ptile)) {
638 struct unit *pfirst = head_of_units_in_focus();
639
640 if (pfirst) {
641 ptile = unit_tile(pfirst);
642 }
643 }
644
645 iterate_outward(&(wld.map), ptile, FC_INFINITY, ptile2) {
646 unit_list_iterate(ptile2->units, punit) {
647 if ((!unit_is_in_focus(punit) || accept_current)
648 && unit_owner(punit) == client.conn.playing
649 && punit->client.focus_status == FOCUS_AVAIL
650 && punit->activity == ACTIVITY_IDLE
651 && !unit_has_orders(punit)
652 && (punit->moves_left > 0 || unit_type_get(punit)->move_rate == 0)
653 && !punit->done_moving
654 && punit->ssa_controller == SSA_NONE) {
655 return punit;
656 }
657 } unit_list_iterate_end;
658 } iterate_outward_end;
659
660 return NULL;
661}
662
663/**********************************************************************/
670 void unit_focus_advance(void)
671{
672 struct unit *candidate = NULL;
673 const int num_units_in_old_focus = get_num_units_in_focus();
674
675 if (NULL == client.conn.playing
676 || !is_player_phase(client.conn.playing, game.info.phase)
677 || !can_client_change_view()) {
678 unit_focus_set(NULL);
679 return;
680 }
681
682 clear_hover_state();
683
684 unit_list_iterate(get_units_in_focus(), punit) {
685 /*
686 * Is the unit which just lost focus a non-AI unit? If yes this
687 * enables the auto end turn.
688 */
689 if (punit->ssa_controller == SSA_NONE) {
690 non_ai_unit_focus = TRUE;
691 break;
692 }
693 } unit_list_iterate_end;
694
695 if (unit_list_size(urgent_focus_queue) > 0) {
696 /* Try top of the urgent list. */
697 struct tile *focus_tile = (get_num_units_in_focus() > 0
698 ? unit_tile(head_of_units_in_focus())
699 : NULL);
700
701 unit_list_both_iterate(urgent_focus_queue, plink, punit) {
702 if ((ACTIVITY_IDLE != punit->activity
703 || unit_has_orders(punit))
704 /* This isn't an action decision needed because of an
705 * ORDER_ACTION_MOVE located in the middle of an order. */
706 && !should_ask_server_for_actions(punit)) {
707 /* We have assigned new orders to this unit since, remove it. */
708 unit_list_erase(urgent_focus_queue, plink);
709 } else if (NULL == focus_tile
710 || focus_tile == unit_tile(punit)) {
711 /* Use the first one found */
712 candidate = punit;
713 break;
714 } else if (NULL == candidate) {
715 candidate = punit;
716 }
717 } unit_list_both_iterate_end;
718
719 if (NULL != candidate) {
720 unit_list_remove(urgent_focus_queue, candidate);
721
722 /* Autocenter on Wakeup, regardless of the local option
723 * "auto_center_on_unit". */
724 if (!tile_visible_and_not_on_border_mapcanvas(unit_tile(candidate))) {
725 center_tile_mapcanvas(unit_tile(candidate));
726 }
727 }
728 }
729
730 if (NULL == candidate) {
731 candidate = find_best_focus_candidate(FALSE);
732
733 if (!candidate) {
734 /* Try for "waiting" units. */
735 unit_list_iterate(client.conn.playing->units, punit) {
736 if (punit->client.focus_status == FOCUS_WAIT) {
737 punit->client.focus_status = FOCUS_AVAIL;
738 }
739 } unit_list_iterate_end;
740 candidate = find_best_focus_candidate(FALSE);
741
742 if (!candidate) {
743 /* Accept current focus unit as last resort. */
744 candidate = find_best_focus_candidate(TRUE);
745 }
746 }
747 }
748
749 unit_focus_set(candidate);
750
751 /*
752 * Handle auto-turn-done mode: If a unit was in focus (did move),
753 * but now none are (no more to move) and there was at least one
754 * non-AI unit this turn which was focused, then fake a Turn Done
755 * keypress.
756 */
757 if (gui_options.auto_turn_done
758 && num_units_in_old_focus > 0
759 && get_num_units_in_focus() == 0
760 && non_ai_unit_focus) {
761 key_end_turn();
762 }
763}
764
765/**********************************************************************/
771 void unit_focus_update(void)
772{
773 if (NULL == client.conn.playing || !can_client_change_view()) {
774 return;
775 }
776
777 if (!can_ask_server_for_actions()) {
778 fc_assert(get_num_units_in_focus() > 0);
779
780 /* An actor unit is asking the player what to do. Don't change the
781 * focus. */
782 return;
783 }
784
785 /* iterate zero times for no units in focus,
786 * otherwise quit for any of the conditions. */
787 unit_list_iterate(get_units_in_focus(), punit) {
788 if ((punit->activity == ACTIVITY_IDLE
789 || punit->activity == ACTIVITY_GOTO
790 || unit_has_orders(punit))
791 && punit->moves_left > 0
792 && !punit->done_moving
793 && punit->ssa_controller == SSA_NONE) {
794 return;
795 }
796 } unit_list_iterate_end;
797
798 unit_focus_advance();
799}
800
801/**********************************************************************/
804 struct unit *find_visible_unit(struct tile *ptile)
805{
806 struct unit *panyowned = NULL, *panyother = NULL, *ptptother = NULL;
807
808 /* If no units here, return nothing. */
809 if (unit_list_size(ptile->units) == 0) {
810 return NULL;
811 }
812
813 /* If a unit is attacking we should show that on top */
814 if (punit_attacking && same_pos(unit_tile(punit_attacking), ptile)) {
815 unit_list_iterate(ptile->units, punit) {
816 if (punit == punit_attacking) {
817 return punit;
818 }
819 } unit_list_iterate_end;
820 }
821
822 /* If a unit is defending we should show that on top */
823 if (punit_defending && same_pos(unit_tile(punit_defending), ptile)) {
824 unit_list_iterate(ptile->units, punit) {
825 if (punit == punit_defending) {
826 return punit;
827 }
828 } unit_list_iterate_end;
829 }
830
831 /* If the unit in focus is at this tile, show that on top */
832 unit_list_iterate(get_units_in_focus(), punit) {
833 if (punit != punit_moving && unit_tile(punit) == ptile) {
834 return punit;
835 }
836 } unit_list_iterate_end;
837
838 /* If a city is here, return nothing (unit hidden by city). */
839 if (tile_city(ptile)) {
840 return NULL;
841 }
842
843 /* Iterate through the units to find the best one we prioritize this way:
844 1: owned transporter.
845 2: any owned unit
846 3: any transporter
847 4: any unit
848 (always return first in stack). */
849 unit_list_iterate(ptile->units, punit)
850 if (unit_owner(punit) == client.conn.playing) {
851 if (!unit_transported(punit)) {
852 if (get_transporter_capacity(punit) > 0) {
853 return punit;
854 } else if (!panyowned) {
855 panyowned = punit;
856 }
857 }
858 } else if (!ptptother && !unit_transported(punit)) {
859 if (get_transporter_capacity(punit) > 0) {
860 ptptother = punit;
861 } else if (!panyother) {
862 panyother = punit;
863 }
864 }
865 unit_list_iterate_end;
866
867 return (panyowned ? panyowned : (ptptother ? ptptother : panyother));
868}
869
870/**********************************************************************/
874 double blink_active_unit(void)
875{
876 static struct timer *blink_timer = NULL;
877 const double blink_time = get_focus_unit_toggle_timeout(tileset);
878
879 if (get_num_units_in_focus() > 0) {
880 if (!blink_timer || timer_read_seconds(blink_timer) > blink_time) {
881 toggle_focus_unit_state(tileset);
882
883 /* If we lag, we don't try to catch up. Instead we just start a
884 * new blink_time on every update. */
885 blink_timer = timer_renew(blink_timer, TIMER_USER, TIMER_ACTIVE,
886 blink_timer != NULL ? NULL : "blink");
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 blink_timer != NULL ? NULL : "blink");
944 timer_start(blink_timer);
945 }
946 return blink_time - timer_read_seconds(blink_timer);
947 }
948
949 return blink_time;
950}
951
952/**********************************************************************/
967 void update_unit_pix_label(struct unit_list *punitlist)
968{
969 int i;
970
971 /* Check for any change in the unit's state. This assumes that a unit's
972 * orders cannot be changed directly but must be removed and then reset. */
973 if (punitlist && unit_list_size(punitlist) > 0
974 && C_S_OVER != client_state()) {
975 /* There used to be a complicated and bug-prone check here to see if
976 * the unit had actually changed. This was misguided since the stacked
977 * units (below) are redrawn in any case. Unless we write a general
978 * system for unit updates here we might as well just redraw it every
979 * time. */
980 struct unit *punit = unit_list_get(punitlist, 0);
981
982 set_unit_icon(-1, punit);
983
984 i = 0; /* index into unit_below_canvas */
985 unit_list_iterate(unit_tile(punit)->units, aunit) {
986 if (aunit != punit) {
987 if (i < num_units_below) {
988 set_unit_icon(i, aunit);
989 }
990 i++;
991 }
992 }
993 unit_list_iterate_end;
994
995 if (i > num_units_below) {
996 set_unit_icons_more_arrow(TRUE);
997 } else {
998 set_unit_icons_more_arrow(FALSE);
999 for (; i < num_units_below; i++) {
1000 set_unit_icon(i, NULL);
1001 }
1002 }
1003 } else {
1004 for (i = -1; i < num_units_below; i++) {
1005 set_unit_icon(i, NULL);
1006 }
1007 set_unit_icons_more_arrow(FALSE);
1008 }
1009}
1010
1011/**********************************************************************/
1014 void set_units_in_combat(struct unit *pattacker, struct unit *pdefender)
1015{
1016 punit_attacking = pattacker;
1017 punit_defending = pdefender;
1018
1019 if (unit_is_in_focus(punit_attacking)
1020 || unit_is_in_focus(punit_defending)) {
1021 /* If one of the units is the focus unit, make sure hidden-focus is
1022 * disabled. We don't just do this as a check later because then
1023 * with a blinking unit it would just disappear again right after the
1024 * battle. */
1025 focus_unit_in_combat(tileset);
1026 }
1027}
1028
1029/**********************************************************************/
1033 void action_selection_no_longer_in_progress(const int old_actor_id)
1034{
1035 /* IDENTITY_NUMBER_ZERO is accepted for cases where the unit is gone
1036 * without a trace. */
1037 fc_assert_msg(old_actor_id == action_selection_in_progress_for
1038 || old_actor_id == IDENTITY_NUMBER_ZERO
1039 || action_selection_in_progress_for == IDENTITY_NUMBER_ZERO,
1040 "Decision taken for %d but selection is for %d.",
1041 old_actor_id, action_selection_in_progress_for);
1042
1043 /* Stop objecting to allowing the next unit to ask. */
1044 action_selection_in_progress_for = IDENTITY_NUMBER_ZERO;
1045
1046 /* Clean up any client specific assumptions. */
1047 action_selection_no_longer_in_progress_gui_specific(old_actor_id);
1048}
1049
1050/**********************************************************************/
1054 void action_decision_clear_want(const int old_actor_id)
1055{
1056 if (game_unit_by_number(old_actor_id) != NULL) {
1057 /* Have the server record that a decision no longer is wanted. */
1058 dsend_packet_unit_sscs_set(&client.conn, old_actor_id,
1059 USSDT_UNQUEUE, IDENTITY_NUMBER_ZERO);
1060 }
1061}
1062
1063/**********************************************************************/
1066 void action_selection_next_in_focus(const int old_actor_id)
1067{
1068 struct unit *old;
1069
1070 old = game_unit_by_number(old_actor_id);
1071
1072 /* Go to the next unit in focus that needs a decision. */
1073 unit_list_iterate(get_units_in_focus(), funit) {
1074 if (old != funit && should_ask_server_for_actions(funit)) {
1075 ask_server_for_actions(funit);
1076 return;
1077 }
1078 } unit_list_iterate_end;
1079}
1080
1081/**********************************************************************/
1084 void action_decision_request(struct unit *actor_unit)
1085{
1086 fc_assert_ret(actor_unit);
1087 fc_assert_ret(actor_unit->action_decision_tile);
1088
1089 if (!unit_is_in_focus(actor_unit)) {
1090 /* Getting feed back may be urgent. A unit standing next to an enemy
1091 * could be killed while waiting. */
1092 unit_focus_urgent(actor_unit);
1093 } else if (can_client_issue_orders()
1094 && can_ask_server_for_actions()) {
1095 /* No need to wait. The actor unit is in focus. No other actor unit
1096 * is currently asking about action selection. */
1097 ask_server_for_actions(actor_unit);
1098 }
1099}
1100
1101/**********************************************************************/
1104 void request_unit_goto(enum unit_orders last_order,
1105 action_id act_id, int sub_tgt_id)
1106{
1107 struct unit_list *punits = get_units_in_focus();
1108
1109 fc_assert_ret(act_id == ACTION_NONE
1110 || last_order == ORDER_PERFORM_ACTION);
1111
1112 if (unit_list_size(punits) == 0) {
1113 return;
1114 }
1115
1116 if (last_order == ORDER_PERFORM_ACTION) {
1117 /* An action has been specified. */
1118 fc_assert_ret(action_id_exists(act_id));
1119
1120 unit_list_iterate(punits, punit) {
1121 if (!unit_can_do_action(punit, act_id)) {
1122 /* This unit can't perform the action specified in the last
1123 * order. */
1124
1125 struct astring astr = ASTRING_INIT;
1126
1127 if (role_units_translations(&astr,
1128 action_id_get_role(act_id),
1129 TRUE)) {
1130 /* ...but other units can perform it. */
1131
1132 create_event(unit_tile(punit), E_BAD_COMMAND, ftc_client,
1133 /* TRANS: Only Nuclear or ICBM can do Explode
1134 * Nuclear. */
1135 _("Only %s can do %s."),
1136 astr_str(&astr),
1137 action_id_name_translation(act_id));
1138
1139 astr_free(&astr);
1140 } else {
1141 create_event(unit_tile(punit), E_BAD_COMMAND, ftc_client,
1142 /* TRANS: Spy can't do Explode Nuclear. */
1143 _("%s can't do %s."),
1144 unit_name_translation(punit),
1145 action_id_name_translation(act_id));
1146 }
1147
1148 return;
1149 }
1150 } unit_list_iterate_end;
1151 }
1152
1153 if (hover_state != HOVER_GOTO && hover_state != HOVER_GOTO_SEL_TGT) {
1154 set_hover_state(punits, HOVER_GOTO, ACTIVITY_LAST, NULL,
1155 NO_TARGET, sub_tgt_id, act_id, last_order);
1156 enter_goto_state(punits);
1157 create_line_at_mouse_pos();
1158 update_unit_info_label(punits);
1159 control_mouse_cursor(NULL);
1160 } else {
1161 fc_assert_ret(goto_is_active());
1162 /* Adding a long range action in the middle isn't handled yet */
1163 fc_assert_ret(hover_state != HOVER_GOTO_SEL_TGT);
1164 goto_add_waypoint();
1165 }
1166}
1167
1168/**********************************************************************/
1171 static bool can_units_attack_at(struct unit_list *punits,
1172 const struct tile *ptile)
1173{
1174 unit_list_iterate(punits, punit) {
1175 if (is_attack_unit(punit)
1176 && can_unit_attack_tile(punit, NULL, ptile)) {
1177 return TRUE;
1178 }
1179 } unit_list_iterate_end;
1180
1181 return FALSE;
1182}
1183
1184/**********************************************************************/
1189 void control_mouse_cursor(struct tile *ptile)
1190{
1191 struct unit *punit = NULL;
1192 struct city *pcity = NULL;
1193 struct unit_list *active_units = get_units_in_focus();
1194 enum cursor_type mouse_cursor_type = CURSOR_DEFAULT;
1195
1196 if (!gui_options.enable_cursor_changes) {
1197 return;
1198 }
1199
1200 if (C_S_RUNNING != client_state()) {
1201 update_mouse_cursor(CURSOR_DEFAULT);
1202 return;
1203 }
1204
1205 if (is_server_busy()) {
1206 /* Server will not accept any commands. */
1207 update_mouse_cursor(CURSOR_WAIT);
1208 return;
1209 }
1210
1211 if (!ptile) {
1212 if (hover_tile) {
1213 /* hover_tile is the tile that was previously under the mouse cursor. */
1214 ptile = hover_tile;
1215 } else {
1216 update_mouse_cursor(CURSOR_DEFAULT);
1217 return;
1218 }
1219 } else {
1220 hover_tile = ptile;
1221 }
1222
1223 punit = find_visible_unit(ptile);
1224 pcity = ptile ? tile_city(ptile) : NULL;
1225
1226 switch (hover_state) {
1227 case HOVER_NONE:
1228 if (NULL != punit
1229 && unit_owner(punit) == client_player()) {
1230 /* Set mouse cursor to select a unit. */
1231 mouse_cursor_type = CURSOR_SELECT;
1232 } else if (NULL != pcity
1233 && can_player_see_city_internals(client.conn.playing, pcity)) {
1234 /* Set mouse cursor to select a city. */
1235 mouse_cursor_type = CURSOR_SELECT;
1236 } else {
1237 /* Set default mouse cursor, because nothing selectable found. */
1238 }
1239 break;
1240 case HOVER_GOTO:
1241 /* Determine if the goto is valid, invalid, nuke or will attack. */
1242 if (is_valid_goto_destination(ptile)) {
1243 if (action_id_has_result_safe(goto_last_action, ACTRES_NUKE_UNITS)
1244 || action_id_has_result_safe(goto_last_action, ACTRES_NUKE)) {
1245 /* Goto results in nuclear attack. */
1246 mouse_cursor_type = CURSOR_NUKE;
1247 } else if (can_units_attack_at(active_units, ptile)) {
1248 /* Goto results in military attack. */
1249 mouse_cursor_type = CURSOR_ATTACK;
1250 } else if (is_enemy_city_tile(ptile, client.conn.playing)) {
1251 /* Goto results in attack of enemy city. */
1252 mouse_cursor_type = CURSOR_ATTACK;
1253 } else {
1254 mouse_cursor_type = CURSOR_GOTO;
1255 }
1256 } else {
1257 mouse_cursor_type = CURSOR_INVALID;
1258 }
1259 break;
1260 case HOVER_PATROL:
1261 if (is_valid_goto_destination(ptile)) {
1262 mouse_cursor_type = CURSOR_PATROL;
1263 } else {
1264 mouse_cursor_type = CURSOR_INVALID;
1265 }
1266 break;
1267 case HOVER_CONNECT:
1268 if (is_valid_goto_destination(ptile)) {
1269 mouse_cursor_type = CURSOR_GOTO;
1270 } else {
1271 mouse_cursor_type = CURSOR_INVALID;
1272 }
1273 break;
1274 case HOVER_TELEPORT:
1275 /* FIXME: check for invalid tiles. */
1276 mouse_cursor_type = CURSOR_TELEPORT;
1277 break;
1278 case HOVER_PARADROP:
1279 /* FIXME: check for invalid tiles. */
1280 mouse_cursor_type = CURSOR_PARADROP;
1281 break;
1282 case HOVER_ACT_SEL_TGT:
1283 case HOVER_GOTO_SEL_TGT:
1284 /* Select a tile to target / find targets on. */
1285 mouse_cursor_type = CURSOR_SELECT;
1286 break;
1287 };
1288
1289 update_mouse_cursor(mouse_cursor_type);
1290}
1291
1292/**********************************************************************/
1295 static bool is_activity_on_tile(struct tile *ptile,
1296 enum unit_activity activity)
1297{
1298 unit_list_iterate(ptile->units, punit) {
1299 if (punit->activity == activity) {
1300 return TRUE;
1301 }
1302 } unit_list_iterate_end;
1303
1304 return FALSE;
1305}
1306
1307/**********************************************************************/
1311 int check_recursive_road_connect(struct tile *ptile,
1312 const struct extra_type *pextra,
1313 const struct unit *punit,
1314 const struct player *pplayer, int rec)
1315{
1316 int activity_mc = 0;
1317 struct terrain *pterrain = tile_terrain(ptile);
1318 const struct civ_map *nmap = &(wld.map);
1319
1320 if (rec > MAX_EXTRA_TYPES) {
1321 return -1;
1322 }
1323
1324 if (!is_extra_caused_by(pextra, EC_ROAD)) {
1325 return -1;
1326 }
1327
1328 extra_deps_iterate(&(pextra->reqs), pdep) {
1329 if (!tile_has_extra(ptile, pdep)) {
1330 int single_mc;
1331
1332 single_mc = check_recursive_road_connect(ptile, pdep, punit,
1333 pplayer, rec + 1);
1334
1335 if (single_mc < 0) {
1336 return -1;
1337 }
1338
1339 activity_mc += single_mc;
1340 }
1341 } extra_deps_iterate_end;
1342
1343 /* Can build road after that? */
1344 if (punit != NULL) {
1345 if (!can_build_road(nmap, extra_road_get(pextra), punit, ptile)) {
1346 return -1;
1347 }
1348 } else if (pplayer != NULL) {
1349 if (!player_can_build_road(nmap, extra_road_get(pextra),
1350 pplayer, ptile)) {
1351 return -1;
1352 }
1353 }
1354
1355 tile_add_extra(ptile, pextra);
1356
1357 activity_mc += terrain_extra_build_time(pterrain, ACTIVITY_GEN_ROAD, pextra);
1358
1359 return activity_mc;
1360}
1361
1362/*******************************************************************/
1366 static bool can_be_irrigated(const struct tile *ptile,
1367 const struct unit *punit)
1368{
1369 struct terrain* pterrain = tile_terrain(ptile);
1370 struct universal for_unit = { .kind = VUT_UTYPE,
1371 .value.utype = unit_type_get(punit)};
1372 struct universal for_tile = { .kind = VUT_TERRAIN,
1373 .value.terrain = tile_terrain(ptile)};
1374
1375 if (T_UNKNOWN == pterrain) {
1376 return FALSE;
1377 }
1378
1379 return action_id_univs_not_blocking(ACTION_IRRIGATE,
1380 &for_unit, &for_tile);
1381}
1382
1383/**********************************************************************/
1389 bool can_unit_do_connect(struct unit *punit,
1390 enum unit_activity activity,
1391 struct extra_type *tgt)
1392{
1393 struct tile *ptile = unit_tile(punit);
1394 struct road_type *proad = NULL;
1395 const struct req_context unit_ctxt = {
1396 .unit = punit,
1397 .unittype = unit_type_get(punit),
1398 };
1399
1400 /* HACK: This code duplicates that in
1401 * can_unit_do_activity_targeted_at(). The general logic here is that
1402 * the connect is allowed if both:
1403 * (1) the unit can do that activity type, in general
1404 * (2) either
1405 * (a) the activity has already been completed at this tile
1406 * (b) it can be done by the unit at this tile. */
1407 switch (activity) {
1408 case ACTIVITY_GEN_ROAD:
1409 {
1410 struct tile *vtile;
1411 int build_time;
1412
1413 fc_assert(is_extra_caused_by(tgt, EC_ROAD));
1414
1415 proad = extra_road_get(tgt);
1416
1417 if (tile_has_road(ptile, proad)) {
1418 /* This tile has road, can unit build road to other tiles too? */
1419 return are_reqs_active(&unit_ctxt, NULL, &tgt->reqs, RPT_POSSIBLE);
1420 }
1421
1422 /* To start connect, unit must be able to build road to this
1423 * particular tile. */
1424 vtile = tile_virtual_new(ptile);
1425 build_time = check_recursive_road_connect(vtile, tgt, punit, NULL, 0);
1426 tile_virtual_destroy(vtile);
1427
1428 return build_time >= 0;
1429 }
1430
1431 case ACTIVITY_IRRIGATE:
1432 /* Special case for irrigation: only irrigate to make S_IRRIGATION,
1433 * never to transform tiles. */
1434 if (!unit_has_type_flag(punit, UTYF_SETTLERS)) {
1435 return FALSE;
1436 }
1437 if (tile_has_extra(ptile, tgt)) {
1438 return are_reqs_active(&unit_ctxt, NULL, &tgt->reqs, RPT_POSSIBLE);
1439 }
1440
1441 return can_be_irrigated(ptile, punit)
1442 && can_build_extra(tgt, punit, ptile)
1443 && !is_activity_on_tile(ptile,
1444 ACTIVITY_MINE);
1445 default:
1446 break;
1447 }
1448
1449 return FALSE;
1450}
1451
1452/**********************************************************************/
1456 void request_unit_connect(enum unit_activity activity,
1457 struct extra_type *tgt)
1458{
1459 struct unit_list *punits = get_units_in_focus();
1460
1461 if (!can_units_do_connect(punits, activity, tgt)) {
1462 return;
1463 }
1464
1465 if (hover_state != HOVER_CONNECT || connect_activity != activity
1466 || (connect_tgt != tgt
1467 && (activity == ACTIVITY_GEN_ROAD
1468 || activity == ACTIVITY_IRRIGATE))) {
1469 set_hover_state(punits, HOVER_CONNECT,
1470 activity, tgt, NO_TARGET, NO_TARGET,
1471 ACTION_NONE, ORDER_LAST);
1472 enter_goto_state(punits);
1473 create_line_at_mouse_pos();
1474 update_unit_info_label(punits);
1475 control_mouse_cursor(NULL);
1476 } else {
1477 fc_assert_ret(goto_is_active());
1478 goto_add_waypoint();
1479 }
1480}
1481
1482/**********************************************************************/
1485 struct unit *request_unit_unload_all(struct unit *punit)
1486{
1487 struct tile *ptile = unit_tile(punit);
1488 struct unit *plast = NULL;
1489
1490 if (get_transporter_capacity(punit) == 0) {
1491 create_event(unit_tile(punit), E_BAD_COMMAND, ftc_client,
1492 _("Only transporter units can be unloaded."));
1493 return NULL;
1494 }
1495
1496 unit_list_iterate(ptile->units, pcargo) {
1497 if (unit_transport_get(pcargo) == punit) {
1498 request_unit_unload(pcargo);
1499
1500 if (pcargo->activity == ACTIVITY_SENTRY) {
1501 dsend_packet_unit_sscs_set(&client.conn, pcargo->id,
1502 USSDT_SENTRY, 0);
1503 }
1504
1505 if (unit_owner(pcargo) == unit_owner(punit)) {
1506 plast = pcargo;
1507 }
1508 }
1509 } unit_list_iterate_end;
1510
1511 return plast;
1512}
1513
1514/**********************************************************************/
1517 void request_unit_airlift(struct unit *punit, struct city *pcity)
1518{
1519 request_do_action(ACTION_AIRLIFT, punit->id, pcity->id, 0, "");
1520}
1521
1522/**********************************************************************/
1526 void request_unit_return(struct unit *punit)
1527{
1528 struct pf_path *path;
1529
1530 if ((path = path_to_nearest_allied_city(punit))) {
1531 int turns = pf_path_last_position(path)->turn;
1532 int max_hp = unit_type_get(punit)->hp;
1533
1534 if (punit->hp + turns *
1535 (get_unit_bonus(punit, EFT_UNIT_RECOVER)
1536 - (max_hp * unit_class_get(punit)->hp_loss_pct / 100))
1537 < max_hp) {
1538 struct unit_order order;
1539
1540 order.order = ORDER_ACTIVITY;
1541 order.dir = DIR8_ORIGIN;
1542 order.activity = ACTIVITY_SENTRY;
1543 order.target = NO_TARGET;
1544 order.sub_target = NO_TARGET;
1545 order.action = ACTION_NONE;
1546 send_goto_path(punit, path, &order);
1547 } else {
1548 send_goto_path(punit, path, NULL);
1549 }
1550 pf_path_destroy(path);
1551 }
1552}
1553
1554/**********************************************************************/
1557 void wakeup_sentried_units(struct tile *ptile)
1558{
1559 if (!can_client_issue_orders()) {
1560 return;
1561 }
1562 unit_list_iterate(ptile->units, punit) {
1563 if (punit->activity == ACTIVITY_SENTRY
1564 && unit_owner(punit) == client.conn.playing) {
1565 request_new_unit_activity(punit, ACTIVITY_IDLE);
1566 }
1567 }
1568 unit_list_iterate_end;
1569}
1570
1571/**********************************************************************/
1574 void request_unit_wakeup(struct unit *punit)
1575{
1576 wakeup_sentried_units(unit_tile(punit));
1577}
1578
1579/**************************************************************************
1580 Defines specific hash tables needed for request_unit_select().
1581**************************************************************************/
1582#define SPECHASH_TAG unit_type
1583#define SPECHASH_IKEY_TYPE struct unit_type *
1584#define SPECHASH_IDATA_TYPE void *
1585#include "spechash.h"
1586
1587#define SPECHASH_TAG continent
1588#define SPECHASH_INT_KEY_TYPE
1589#define SPECHASH_IDATA_TYPE void *
1590#include "spechash.h"
1591
1592/**********************************************************************/
1595 void request_unit_select(struct unit_list *punits,
1596 enum unit_select_type_mode seltype,
1597 enum unit_select_location_mode selloc)
1598{
1599 const struct player *pplayer;
1600 const struct tile *ptile;
1601 struct unit *punit_first;
1602 struct tile_hash *tile_table;
1603 struct unit_type_hash *type_table;
1604 struct continent_hash *cont_table;
1605
1606 if (!can_client_change_view() || !punits
1607 || unit_list_size(punits) < 1) {
1608 return;
1609 }
1610
1611 punit_first = unit_list_get(punits, 0);
1612
1613 if (seltype == SELTYPE_SINGLE) {
1614 unit_focus_set(punit_first);
1615 return;
1616 }
1617
1618 pplayer = unit_owner(punit_first);
1619 tile_table = tile_hash_new();
1620 type_table = unit_type_hash_new();
1621 cont_table = continent_hash_new();
1622
1623 unit_list_iterate(punits, punit) {
1624 if (seltype == SELTYPE_SAME) {
1625 unit_type_hash_insert(type_table, unit_type_get(punit), NULL);
1626 }
1627
1628 ptile = unit_tile(punit);
1629 if (selloc == SELLOC_TILE) {
1630 tile_hash_insert(tile_table, ptile, NULL);
1631 } else if (selloc == SELLOC_CONT) {
1632 continent_hash_insert(cont_table, tile_continent(ptile), NULL);
1633 }
1634 } unit_list_iterate_end;
1635
1636 if (selloc == SELLOC_TILE) {
1637 tile_hash_iterate(tile_table, hash_tile) {
1638 unit_list_iterate(hash_tile->units, punit) {
1639 if (unit_owner(punit) != pplayer) {
1640 continue;
1641 }
1642 if (seltype == SELTYPE_SAME
1643 && !unit_type_hash_lookup(type_table, unit_type_get(punit), NULL)) {
1644 continue;
1645 }
1646 unit_focus_add(punit);
1647 } unit_list_iterate_end;
1648 } tile_hash_iterate_end;
1649 } else {
1650 unit_list_iterate(pplayer->units, punit) {
1651 ptile = unit_tile(punit);
1652 if ((seltype == SELTYPE_SAME
1653 && !unit_type_hash_lookup(type_table, unit_type_get(punit), NULL))
1654 || (selloc == SELLOC_CONT
1655 && !continent_hash_lookup(cont_table, tile_continent(ptile),
1656 NULL))) {
1657 continue;
1658 }
1659
1660 unit_focus_add(punit);
1661 } unit_list_iterate_end;
1662 }
1663
1664 tile_hash_destroy(tile_table);
1665 unit_type_hash_destroy(type_table);
1666 continent_hash_destroy(cont_table);
1667}
1668
1669/**********************************************************************/
1673 static bool action_requires_confirmation(action_id act,
1674 char *buf, size_t bufsize)
1675{
1676 fc_assert(buf != NULL || bufsize == 0);
1677
1678 if (bufsize > 0) {
1679 buf[0] = '\0';
1680 }
1681
1682 if (act == ACTION_JOIN_CITY) {
1683 if (bufsize > 0) {
1684 fc_snprintf(buf, bufsize, _("Joining a city uses the unit"));
1685 }
1686
1687 return TRUE;
1688 }
1689
1690 return FALSE;
1691}
1692
1693/**********************************************************************/
1704 void request_do_action(action_id action, int actor_id,
1705 int target_id, int sub_tgt, const char *name)
1706{
1707 char buf[400];
1708
1709 if (action_requires_confirmation(action, buf, sizeof(buf))) {
1710 struct act_confirmation_data *data = fc_malloc(sizeof(struct act_confirmation_data));
1711
1712 data->act = action;
1713 data->actor = actor_id;
1714 data->target = target_id;
1715 data->tgt_sub = sub_tgt;
1716
1717 if (name != NULL) {
1718 data->name = fc_strdup(name);
1719 } else {
1720 data->name = NULL;
1721 }
1722
1723 request_action_confirmation(buf, data);
1724 } else {
1725 struct unit *actor_unit = game_unit_by_number(actor_id);
1726
1727 /* Giving an order takes back control. */
1728 request_unit_ssa_set(actor_unit, SSA_NONE);
1729
1730 dsend_packet_unit_do_action(&client.conn,
1731 actor_id, target_id, sub_tgt, name,
1732 action);
1733 }
1734}
1735
1736/**********************************************************************/
1740 void action_confirmation(struct act_confirmation_data *data, bool confirm)
1741{
1742 if (confirm) {
1743 struct unit *actor_unit = game_unit_by_number(data->actor);
1744
1745 if (actor_unit != NULL) {
1746 /* Giving an order takes back control. */
1747 request_unit_ssa_set(actor_unit, SSA_NONE);
1748
1749 dsend_packet_unit_do_action(&client.conn,
1750 data->actor,
1751 data->target,
1752 data->tgt_sub,
1753 data->name,
1754 data->act);
1755 }
1756 }
1757
1758 if (data->name != NULL) {
1759 free(data->name);
1760 }
1761
1762 free(data);
1763}
1764
1765/**********************************************************************/
1772 void request_action_details(action_id action, int actor_id,
1773 int target_id)
1774{
1775 dsend_packet_unit_action_query(&client.conn,
1776 actor_id, target_id, action,
1777 /* Users that need the answer in the
1778 * background should send the packet them
1779 * self. At least for now. */
1780 REQEST_PLAYER_INITIATED);
1781}
1782
1783/**********************************************************************/
1791 void request_unit_build_city(struct unit *punit)
1792{
1793 struct city *pcity;
1794
1795 if ((pcity = tile_city(unit_tile(punit)))) {
1796 /* Try to join the city. */
1797 request_do_action(ACTION_JOIN_CITY, punit->id, pcity->id, 0, "");
1798 } else {
1799 /* The reply will trigger a dialog to name the new city. */
1800 dsend_packet_city_name_suggestion_req(&client.conn, punit->id);
1801 }
1802}
1803
1804/**********************************************************************/
1810 void request_unit_non_action_move(struct unit *punit,
1811 struct tile *dest_tile)
1812{
1813 struct packet_unit_orders p;
1814 int dir;
1815
1816 dir = get_direction_for_step(&(wld.map), unit_tile(punit), dest_tile);
1817
1818 if (dir == -1) {
1819 /* The unit isn't located next to the destination tile. */
1820 return;
1821 }
1822
1823 memset(&p, 0, sizeof(p));
1824
1825 p.repeat = FALSE;
1826 p.vigilant = FALSE;
1827
1828 p.unit_id = punit->id;
1829 p.src_tile = tile_index(unit_tile(punit));
1830 p.dest_tile = tile_index(dest_tile);
1831
1832 p.length = 1;
1833 p.orders[0].order = ORDER_MOVE;
1834 p.orders[0].dir = dir;
1835 p.orders[0].activity = ACTIVITY_LAST;
1836 p.orders[0].target = NO_TARGET;
1837 p.orders[0].sub_target = NO_TARGET;
1838 p.orders[0].action = ACTION_NONE;
1839
1840 request_unit_ssa_set(punit, SSA_NONE);
1841 send_packet_unit_orders(&client.conn, &p);
1842}
1843
1844/**********************************************************************/
1853 void request_move_unit_direction(struct unit *punit, int dir)
1854{
1855 struct packet_unit_orders p;
1856 struct tile *dest_tile;
1857
1858 /* Catches attempts to move off map */
1859 dest_tile = mapstep(&(wld.map), unit_tile(punit), dir);
1860 if (!dest_tile) {
1861 return;
1862 }
1863
1864 if (!can_unit_exist_at_tile(&(wld.map), punit, dest_tile)) {
1865 if (request_transport(punit, dest_tile)) {
1866 return;
1867 }
1868 }
1869
1870 /* The goto system isn't used to send the order because that would
1871 * prevent direction movement from overriding it.
1872 * Example of a situation when overriding the goto system is useful:
1873 * The goto system creates a longer path to make a move legal. The player
1874 * wishes to order the illegal move so the server will explain why the
1875 * short move is illegal. */
1876
1877 memset(&p, 0, sizeof(p));
1878
1879 p.repeat = FALSE;
1880 p.vigilant = FALSE;
1881
1882 p.unit_id = punit->id;
1883 p.src_tile = tile_index(unit_tile(punit));
1884 p.dest_tile = tile_index(dest_tile);
1885
1886 p.length = 1;
1887 p.orders[0].order = (gui_options.popup_last_move_to_allied
1888 ? ORDER_ACTION_MOVE : ORDER_MOVE);
1889 p.orders[0].dir = dir;
1890 p.orders[0].activity = ACTIVITY_LAST;
1891 p.orders[0].target = NO_TARGET;
1892 p.orders[0].sub_target = NO_TARGET;
1893 p.orders[0].action = ACTION_NONE;
1894
1895 request_unit_ssa_set(punit, SSA_NONE);
1896 send_packet_unit_orders(&client.conn, &p);
1897}
1898
1899/**********************************************************************/
1903 void request_new_unit_activity(struct unit *punit, enum unit_activity act)
1904{
1905 request_new_unit_activity_targeted(punit, act, NULL);
1906}
1907
1908/**********************************************************************/
1912 void request_new_unit_activity_targeted(struct unit *punit,
1913 enum unit_activity act,
1914 struct extra_type *tgt)
1915{
1916 if (!can_client_issue_orders()) {
1917 return;
1918 }
1919
1920 /* Callers rely on this to take back control from server side agents. */
1921 request_unit_ssa_set(punit, SSA_NONE);
1922
1923 if (tgt == NULL) {
1924 dsend_packet_unit_change_activity(&client.conn, punit->id, act, EXTRA_NONE);
1925 } else {
1926 dsend_packet_unit_change_activity(&client.conn, punit->id, act, extra_index(tgt));
1927 }
1928}
1929
1930/**********************************************************************/
1933 static void client_disband_unit_data_destroy(void *p)
1934{
1935 struct client_disband_unit_data *data = p;
1936
1937 free(data);
1938}
1939
1940/**********************************************************************/
1943 static void do_disband_alternative(void *p)
1944{
1945 struct unit *punit;
1946 struct city *pcity;
1947 struct tile *ptile;
1948 int last_request_id_used;
1949 struct client_disband_unit_data *next;
1950 struct client_disband_unit_data *data = p;
1951 int act;
1952
1953 fc_assert_ret(can_client_issue_orders());
1954
1955 /* Fetch the unit to get rid of. */
1956 punit = player_unit_by_number(client_player(), data->unit_id);
1957
1958 if (punit == NULL) {
1959 /* Success! It is gone. */
1960 return;
1961 }
1962
1963 if (data->alt == -1) {
1964 /* All alternatives have been tried. */
1965 create_event(unit_tile(punit), E_BAD_COMMAND, ftc_client,
1966 /* TRANS: Unable to get rid of Leader. */
1967 _("Unable to get rid of %s."),
1968 unit_name_translation(punit));
1969 return;
1970 }
1971
1972 act = disband_unit_alternatives[data->alt];
1973
1974 /* Prepare the data for the next try in case this try fails. */
1975 next = fc_malloc(sizeof(struct client_disband_unit_data));
1976 next->unit_id = data->unit_id;
1977 next->alt = data->alt - 1;
1978
1979 /* Latest request ID before trying to send a request. */
1980 last_request_id_used = client.conn.client.last_request_id_used;
1981
1982 /* Send a request to the server unless it is known to be pointless. */
1983 switch (action_id_get_target_kind(act)) {
1984 case ATK_CITY:
1985 if ((pcity = tile_city(unit_tile(punit)))
1986 && action_prob_possible(action_prob_vs_city(punit, act, pcity))) {
1987 request_do_action(act, punit->id, pcity->id, 0, "");
1988 }
1989 break;
1990 case ATK_UNIT:
1991 if (action_prob_possible(action_prob_vs_unit(punit, act, punit))) {
1992 request_do_action(act, punit->id, punit->id, 0, "");
1993 }
1994 break;
1995 case ATK_UNITS:
1996 if ((ptile = unit_tile(punit))
1997 && action_prob_possible(action_prob_vs_stack(punit, act, ptile))) {
1998 request_do_action(act, punit->id, ptile->index, 0, "");
1999 }
2000 break;
2001 case ATK_TILE:
2002 if ((ptile = unit_tile(punit))
2003 && action_prob_possible(action_prob_vs_tile(punit, act, ptile, NULL))) {
2004 request_do_action(act, punit->id, ptile->index, 0, "");
2005 }
2006 break;
2007 case ATK_EXTRAS:
2008 if ((ptile = unit_tile(punit))
2009 && action_prob_possible(action_prob_vs_extras(punit, act,
2010 ptile, NULL))) {
2011 request_do_action(act, punit->id, ptile->index, 0, "");
2012 }
2013 break;
2014 case ATK_SELF:
2015 if (action_prob_possible(action_prob_self(punit, act))) {
2016 request_do_action(act, punit->id, punit->id, 0, "");
2017 }
2018 break;
2019 case ATK_COUNT:
2020 fc_assert(action_id_get_target_kind(act) != ATK_COUNT);
2021 break;
2022 }
2023
2024 if (last_request_id_used != client.conn.client.last_request_id_used) {
2025 /* A request was sent. */
2026
2027 /* Check if it worked. Move on if it didn't. */
2028 update_queue_connect_processing_finished_full
2029 (client.conn.client.last_request_id_used,
2030 do_disband_alternative, next,
2031 client_disband_unit_data_destroy);
2032 } else {
2033 /* No request was sent. */
2034
2035 /* Move on. */
2036 do_disband_alternative(next);
2037
2038 /* Won't be freed by anyone else. */
2039 client_disband_unit_data_destroy(next);
2040 }
2041}
2042
2043/**********************************************************************/
2046 void request_unit_disband(struct unit *punit)
2047{
2048 struct client_disband_unit_data *data;
2049
2050 /* Set up disband data. Start at the end of the array. */
2051 data = fc_malloc(sizeof(struct client_disband_unit_data));
2052 data->unit_id = punit->id;
2053 data->alt = 2;
2054
2055 /* Begin. */
2056 do_disband_alternative(data);
2057
2058 /* Won't be freed by anyone else. */
2059 client_disband_unit_data_destroy(data);
2060}
2061
2062/**********************************************************************/
2065 void request_unit_change_homecity(struct unit *punit)
2066{
2067 struct city *pcity = tile_city(unit_tile(punit));
2068
2069 if (pcity) {
2070 request_do_action(ACTION_HOME_CITY, punit->id, pcity->id, 0, "");
2071 }
2072}
2073
2074/**********************************************************************/
2077 void request_unit_upgrade(struct unit *punit)
2078{
2079 struct city *pcity = tile_city(unit_tile(punit));
2080
2081 if (pcity) {
2082 request_do_action(ACTION_UPGRADE_UNIT, punit->id, pcity->id, 0, "");
2083 }
2084}
2085
2086/**********************************************************************/
2089 void request_unit_convert(struct unit *punit)
2090{
2091 request_new_unit_activity(punit, ACTIVITY_CONVERT);
2092}
2093
2094/**********************************************************************/
2099 void request_unit_ssa_set(const struct unit *punit,
2100 enum server_side_agent agent)
2101{
2102 if (punit) {
2103 dsend_packet_unit_server_side_agent_set(&client.conn, punit->id,
2104 agent);
2105 }
2106}
2107
2108/**********************************************************************/
2112 void request_unit_autosettlers(const struct unit *punit)
2113{
2114 if (punit && can_unit_do_autosettlers(punit)) {
2115 request_unit_ssa_set(punit, SSA_AUTOSETTLER);
2116 } else if (punit) {
2117 create_event(unit_tile(punit), E_BAD_COMMAND, ftc_client,
2118 _("Only settler units can be put into auto mode."));
2119 }
2120}
2121
2122/**********************************************************************/
2127 void request_unit_load(struct unit *pcargo, struct unit *ptrans,
2128 struct tile *ptile)
2129{
2130 if (!ptrans) {
2131 ptrans = transporter_for_unit(pcargo);
2132 }
2133
2134 if (ptrans
2135 && can_client_issue_orders()
2136 && could_unit_load(pcargo, ptrans)) {
2137 action_by_result_iterate(paction,
2138 same_pos(unit_tile(pcargo), ptile)
2139 ? ACTRES_TRANSPORT_BOARD
2140 : ACTRES_TRANSPORT_EMBARK) {
2141 enum gen_action act_id = action_id(paction);
2142
2143 if (action_prob_possible(action_prob_vs_unit(pcargo, act_id,
2144 ptrans))) {
2145 /* Try the first action that may be legal. */
2146 /* Implement something like do_disband_alternative() if a ruleset
2147 * appears where this isn't good enough. */
2148 request_do_action(act_id, pcargo->id, ptrans->id, 0, "");
2149 break;
2150 }
2151 } action_by_result_iterate_end;
2152
2153 /* Sentry the unit. */
2154 /* FIXME: Should not sentry if above loading fails (transport moved away,
2155 * or filled already in server side) */
2156 dsend_packet_unit_sscs_set(&client.conn, pcargo->id,
2157 USSDT_SENTRY, 1);
2158 }
2159}
2160
2161/**********************************************************************/
2165 void request_unit_unload(struct unit *pcargo)
2166{
2167 struct unit *ptrans = unit_transport_get(pcargo);
2168
2169 if (can_client_issue_orders()
2170 && ptrans != NULL
2171 && can_unit_unload(pcargo, ptrans)
2172 && can_unit_survive_at_tile(&(wld.map), pcargo, unit_tile(pcargo))) {
2173 if (unit_owner(pcargo) == client.conn.playing) {
2174 request_do_action(ACTION_TRANSPORT_DEBOARD,
2175 pcargo->id, ptrans->id, 0, "");
2176 } else {
2177 request_do_action(ACTION_TRANSPORT_UNLOAD,
2178 ptrans->id, pcargo->id, 0, "");
2179 }
2180
2181 if (unit_owner(pcargo) == client.conn.playing
2182 && pcargo->activity == ACTIVITY_SENTRY) {
2183 /* Activate the unit. */
2184 dsend_packet_unit_sscs_set(&client.conn, pcargo->id,
2185 USSDT_SENTRY, 0);
2186 }
2187 }
2188}
2189
2190/**********************************************************************/
2194 void request_unit_caravan_action(struct unit *punit, action_id action)
2195{
2196 struct city *target_city;
2197
2198 if (!((target_city = tile_city(unit_tile(punit))))) {
2199 return;
2200 }
2201
2202 if (action == ACTION_TRADE_ROUTE) {
2203 request_do_action(ACTION_TRADE_ROUTE, punit->id,
2204 target_city->id, 0, "");
2205 } else if (action == ACTION_HELP_WONDER) {
2206 request_do_action(ACTION_HELP_WONDER, punit->id,
2207 target_city->id, 0, "");
2208 } else {
2209 log_error("request_unit_caravan_action() Bad action (%d)", action);
2210 }
2211}
2212
2213/**********************************************************************/
2217 void request_unit_paradrop(struct unit_list *punits)
2218{
2219 bool can = FALSE;
2220 struct tile *offender = NULL;
2221
2222 if (unit_list_size(punits) == 0) {
2223 return;
2224 }
2225 unit_list_iterate(punits, punit) {
2226 if (can_unit_paradrop(&(wld.map), punit)) {
2227 can = TRUE;
2228 break;
2229 }
2230 if (!offender) { /* Take first offender tile/unit */
2231 offender = unit_tile(punit);
2232 }
2233 } unit_list_iterate_end;
2234 if (can) {
2235 create_event(unit_tile(unit_list_get(punits, 0)), E_BEGINNER_HELP,
2236 ftc_client,
2237 /* TRANS: paradrop target tile. */
2238 _("Click on a tile to paradrop to it."));
2239
2240 set_hover_state(punits, HOVER_PARADROP, ACTIVITY_LAST, NULL,
2241 NO_TARGET, NO_TARGET, ACTION_NONE, ORDER_LAST);
2242 update_unit_info_label(punits);
2243 } else {
2244 create_event(offender, E_BAD_COMMAND, ftc_client,
2245 _("Only paratrooper units can do this."));
2246 }
2247}
2248
2249/**********************************************************************/
2253 static void request_unit_teleport(struct unit_list *punits)
2254{
2255 bool can = FALSE;
2256 struct tile *offender = NULL;
2257
2258 if (unit_list_size(punits) == 0) {
2259 return;
2260 }
2261
2262 unit_list_iterate(punits, punit) {
2263 if (can_unit_teleport(&(wld.map), punit)) {
2264 can = TRUE;
2265 break;
2266 }
2267 if (!offender) { /* Take first offender tile/unit */
2268 offender = unit_tile(punit);
2269 }
2270 } unit_list_iterate_end;
2271
2272 if (can) {
2273 create_event(unit_tile(unit_list_get(punits, 0)), E_BEGINNER_HELP,
2274 ftc_client,
2275 /* TRANS: teleport target tile. */
2276 _("Click on a tile to teleport to it."));
2277
2278 set_hover_state(punits, HOVER_TELEPORT, ACTIVITY_LAST, NULL,
2279 NO_TARGET, NO_TARGET, ACTION_NONE, ORDER_LAST);
2280 update_unit_info_label(punits);
2281 } else {
2282 create_event(offender, E_BAD_COMMAND, ftc_client,
2283 _("Only teleporting units can do this."));
2284 }
2285}
2286
2287/**********************************************************************/
2290 void request_unit_patrol(void)
2291{
2292 struct unit_list *punits = get_units_in_focus();
2293
2294 if (unit_list_size(punits) == 0) {
2295 return;
2296 }
2297
2298 if (hover_state != HOVER_PATROL) {
2299 set_hover_state(punits, HOVER_PATROL, ACTIVITY_LAST, NULL,
2300 NO_TARGET, NO_TARGET, ACTION_NONE, ORDER_LAST);
2301 update_unit_info_label(punits);
2302 enter_goto_state(punits);
2303 create_line_at_mouse_pos();
2304 } else {
2305 fc_assert_ret(goto_is_active());
2306 goto_add_waypoint();
2307 }
2308}
2309
2310/**********************************************************************/
2313 void request_unit_sentry(struct unit *punit)
2314{
2315 if (punit->activity != ACTIVITY_SENTRY
2316 && can_unit_do_activity_client(punit, ACTIVITY_SENTRY)) {
2317 request_new_unit_activity(punit, ACTIVITY_SENTRY);
2318 }
2319}
2320
2321/**********************************************************************/
2324 void request_unit_fortify(struct unit *punit)
2325{
2326 if (punit->activity != ACTIVITY_FORTIFYING
2327 && can_unit_do_activity_client(punit, ACTIVITY_FORTIFYING)) {
2328 request_new_unit_activity(punit, ACTIVITY_FORTIFYING);
2329 }
2330}
2331
2332/**********************************************************************/
2335 void request_unit_pillage(struct unit *punit)
2336{
2337 if (!game.info.pillage_select) {
2338 /* Leave choice up to the server */
2339 request_new_unit_activity_targeted(punit, ACTIVITY_PILLAGE, NULL);
2340 } else {
2341 bv_extras pspossible;
2342 int count = 0;
2343
2344 BV_CLR_ALL(pspossible);
2345 extra_type_iterate(potential) {
2346 if (can_unit_do_activity_targeted_client(punit, ACTIVITY_PILLAGE,
2347 potential)) {
2348 BV_SET(pspossible, extra_index(potential));
2349 count++;
2350 }
2351 } extra_type_iterate_end;
2352
2353 if (count > 1) {
2354 popup_pillage_dialog(punit, pspossible);
2355 } else {
2356 /* Should be only one choice... */
2357 struct extra_type *target = get_preferred_pillage(pspossible);
2358
2359 if (target != NULL) {
2360 request_new_unit_activity_targeted(punit, ACTIVITY_PILLAGE, target);
2361 }
2362 }
2363 }
2364}
2365
2366/**********************************************************************/
2369 void request_toggle_city_outlines(void)
2370{
2371 if (!can_client_change_view()) {
2372 return;
2373 }
2374
2375 gui_options.draw_city_outlines = !gui_options.draw_city_outlines;
2376 update_map_canvas_visible();
2377}
2378
2379/**********************************************************************/
2382 void request_toggle_city_output(void)
2383{
2384 if (!can_client_change_view()) {
2385 return;
2386 }
2387
2388 gui_options.draw_city_output = !gui_options.draw_city_output;
2389 update_map_canvas_visible();
2390}
2391
2392/**********************************************************************/
2395 void request_toggle_map_grid(void)
2396{
2397 if (!can_client_change_view()) {
2398 return;
2399 }
2400
2401 gui_options.draw_map_grid ^= 1;
2402 update_map_canvas_visible();
2403}
2404
2405/**********************************************************************/
2408 void request_toggle_map_borders(void)
2409{
2410 if (!can_client_change_view()) {
2411 return;
2412 }
2413
2414 gui_options.draw_borders ^= 1;
2415 update_map_canvas_visible();
2416}
2417
2418/**********************************************************************/
2421 void request_toggle_map_native(void)
2422{
2423 if (!can_client_change_view()) {
2424 return;
2425 }
2426
2427 gui_options.draw_native ^= 1;
2428 update_map_canvas_visible();
2429}
2430
2431/**********************************************************************/
2434 void request_toggle_city_full_bar(void)
2435{
2436 if (!can_client_change_view()) {
2437 return;
2438 }
2439
2440 gui_options.draw_full_citybar ^= 1;
2441 update_map_canvas_visible();
2442}
2443
2444/**********************************************************************/
2447 void request_toggle_city_names(void)
2448{
2449 if (!can_client_change_view()) {
2450 return;
2451 }
2452
2453 gui_options.draw_city_names ^= 1;
2454 update_map_canvas_visible();
2455}
2456
2457/**********************************************************************/
2460 void request_toggle_city_growth(void)
2461{
2462 if (!can_client_change_view()) {
2463 return;
2464 }
2465
2466 gui_options.draw_city_growth ^= 1;
2467 update_map_canvas_visible();
2468}
2469
2470/**********************************************************************/
2473 void request_toggle_city_productions(void)
2474{
2475 if (!can_client_change_view()) {
2476 return;
2477 }
2478
2479 gui_options.draw_city_productions ^= 1;
2480 update_map_canvas_visible();
2481}
2482
2483/**********************************************************************/
2486 void request_toggle_city_buycost(void)
2487{
2488 if (!can_client_change_view()) {
2489 return;
2490 }
2491
2492 gui_options.draw_city_buycost ^= 1;
2493 update_map_canvas_visible();
2494}
2495
2496/**********************************************************************/
2499 void request_toggle_city_trade_routes(void)
2500{
2501 if (!can_client_change_view()) {
2502 return;
2503 }
2504
2505 gui_options.draw_city_trade_routes ^= 1;
2506 update_map_canvas_visible();
2507}
2508
2509/**********************************************************************/
2512 void request_toggle_unit_stack_size(void)
2513{
2514 if (!can_client_change_view()) {
2515 return;
2516 }
2517
2518 gui_options.draw_unit_stack_size ^= 1;
2519 update_map_canvas_visible();
2520}
2521
2522/**********************************************************************/
2525 void request_toggle_terrain(void)
2526{
2527 if (!can_client_change_view()) {
2528 return;
2529 }
2530
2531 gui_options.draw_terrain ^= 1;
2532 update_map_canvas_visible();
2533}
2534
2535/**********************************************************************/
2538 void request_toggle_coastline(void)
2539{
2540 if (!can_client_change_view()) {
2541 return;
2542 }
2543
2544 gui_options.draw_coastline ^= 1;
2545 update_map_canvas_visible();
2546}
2547
2548/**********************************************************************/
2551 void request_toggle_paths(void)
2552{
2553 if (!can_client_change_view()) {
2554 return;
2555 }
2556
2557 gui_options.draw_paths ^= 1;
2558 update_map_canvas_visible();
2559}
2560
2561/**********************************************************************/
2564 void request_toggle_irrigation(void)
2565{
2566 if (!can_client_change_view()) {
2567 return;
2568 }
2569
2570 gui_options.draw_irrigation ^= 1;
2571 update_map_canvas_visible();
2572}
2573
2574/**********************************************************************/
2577 void request_toggle_mines(void)
2578{
2579 if (!can_client_change_view()) {
2580 return;
2581 }
2582
2583 gui_options.draw_mines ^= 1;
2584 update_map_canvas_visible();
2585}
2586
2587/**********************************************************************/
2590 void request_toggle_bases(void)
2591{
2592 if (!can_client_change_view()) {
2593 return;
2594 }
2595
2596 gui_options.draw_fortress_airbase ^= 1;
2597 update_map_canvas_visible();
2598}
2599
2600/**********************************************************************/
2603 void request_toggle_resources(void)
2604{
2605 if (!can_client_change_view()) {
2606 return;
2607 }
2608
2609 gui_options.draw_specials ^= 1;
2610 update_map_canvas_visible();
2611}
2612
2613/**********************************************************************/
2616 void request_toggle_huts(void)
2617{
2618 if (!can_client_change_view()) {
2619 return;
2620 }
2621
2622 gui_options.draw_huts ^= 1;
2623 update_map_canvas_visible();
2624}
2625
2626/**********************************************************************/
2629 void request_toggle_pollution(void)
2630{
2631 if (!can_client_change_view()) {
2632 return;
2633 }
2634
2635 gui_options.draw_pollution ^= 1;
2636 update_map_canvas_visible();
2637}
2638
2639/**********************************************************************/
2642 void request_toggle_cities(void)
2643{
2644 if (!can_client_change_view()) {
2645 return;
2646 }
2647
2648 gui_options.draw_cities ^= 1;
2649 update_map_canvas_visible();
2650}
2651
2652/**********************************************************************/
2655 void request_toggle_units(void)
2656{
2657 if (!can_client_change_view()) {
2658 return;
2659 }
2660
2661 gui_options.draw_units ^= 1;
2662 update_map_canvas_visible();
2663}
2664
2665/**********************************************************************/
2668 void request_toggle_unit_solid_bg(void)
2669{
2670 if (!can_client_change_view()) {
2671 return;
2672 }
2673
2674 gui_options.solid_color_behind_units ^= 1;
2675 update_map_canvas_visible();
2676}
2677
2678/**********************************************************************/
2681 void request_toggle_unit_shields(void)
2682{
2683 if (!can_client_change_view()) {
2684 return;
2685 }
2686
2687 gui_options.draw_unit_shields ^= 1;
2688 update_map_canvas_visible();
2689}
2690
2691/**********************************************************************/
2694 void request_toggle_focus_unit(void)
2695{
2696 if (!can_client_change_view()) {
2697 return;
2698 }
2699
2700 gui_options.draw_focus_unit ^= 1;
2701 update_map_canvas_visible();
2702}
2703
2704/**********************************************************************/
2707 void request_toggle_fog_of_war(void)
2708{
2709 if (!can_client_change_view()) {
2710 return;
2711 }
2712
2713 gui_options.draw_fog_of_war ^= 1;
2714 update_map_canvas_visible();
2715 refresh_overview_canvas();
2716}
2717
2718/**********************************************************************/
2721 void request_center_focus_unit(void)
2722{
2723 struct tile *ptile = find_a_focus_unit_tile_to_center_on();
2724
2725 if (ptile) {
2726 center_tile_mapcanvas(ptile);
2727 }
2728}
2729
2730/**********************************************************************/
2734 void request_units_wait(struct unit_list *punits)
2735{
2736 unit_list_iterate(punits, punit) {
2737 punit->client.focus_status = FOCUS_WAIT;
2738 } unit_list_iterate_end;
2739 if (punits == get_units_in_focus()) {
2740 unit_focus_advance();
2741 }
2742}
2743
2744/**********************************************************************/
2747 void request_unit_move_done(void)
2748{
2749 if (get_num_units_in_focus() > 0) {
2750 enum unit_focus_status new_status = FOCUS_DONE;
2751 unit_list_iterate(get_units_in_focus(), punit) {
2752 /* If any of the focused units are busy, keep all of them
2753 * in focus; another tap of the key will dismiss them */
2754 if (punit->activity != ACTIVITY_IDLE) {
2755 new_status = FOCUS_WAIT;
2756 }
2757 } unit_list_iterate_end;
2758 unit_list_iterate(get_units_in_focus(), punit) {
2759 clear_unit_orders(punit);
2760 punit->client.focus_status = new_status;
2761 } unit_list_iterate_end;
2762 if (new_status == FOCUS_DONE) {
2763 unit_focus_advance();
2764 }
2765 }
2766}
2767
2768/**********************************************************************/
2773 void do_move_unit(struct unit *punit, struct unit *target_unit)
2774{
2775 struct tile *src_tile = unit_tile(punit);
2776 struct tile *dst_tile = unit_tile(target_unit);
2777 bool was_teleported, do_animation;
2778 bool in_focus = unit_is_in_focus(punit);
2779
2780 was_teleported = !is_tiles_adjacent(src_tile, dst_tile);
2781 do_animation = (!was_teleported && gui_options.smooth_move_unit_msec > 0);
2782
2783 if (!was_teleported
2784 && punit->activity != ACTIVITY_SENTRY
2785 && !unit_transported(punit)) {
2786 audio_play_sound(unit_type_get(punit)->sound_move,
2787 unit_type_get(punit)->sound_move_alt,
2788 NULL);
2789 }
2790
2791 if (unit_owner(punit) == client.conn.playing
2792 && gui_options.auto_center_on_unit
2793 && !unit_has_orders(punit)
2794 && punit->activity != ACTIVITY_GOTO
2795 && punit->activity != ACTIVITY_SENTRY
2796 && ((gui_options.auto_center_on_automated
2797 && punit->ssa_controller != SSA_NONE)
2798 || (punit->ssa_controller == SSA_NONE))
2799 && !tile_visible_and_not_on_border_mapcanvas(dst_tile)) {
2800 center_tile_mapcanvas(dst_tile);
2801 }
2802
2803 if (hover_state != HOVER_NONE && in_focus) {
2804 /* Cancel current goto/patrol/connect/nuke command. */
2805 clear_hover_state();
2806 update_unit_info_label(get_units_in_focus());
2807 }
2808
2809 unit_list_remove(src_tile->units, punit);
2810
2811 if (!unit_transported(punit)) {
2812 /* Mark the unit as moving unit, then find_visible_unit() won't return
2813 * it. It is especially useful to don't draw many times the unit when
2814 * refreshing the canvas. */
2815 punit_moving = punit;
2816
2817 /* We have to refresh the tile before moving. This will draw
2818 * the tile without the unit (because it was unlinked above). */
2819 refresh_unit_mapcanvas(punit, src_tile, TRUE, FALSE);
2820
2821 if (!gui_options.auto_center_on_automated
2822 && punit->ssa_controller != SSA_NONE) {
2823 /* Dont animate automatic units */
2824 } else if (do_animation) {
2825 int dx, dy;
2826
2827 /* For the duration of the animation the unit exists at neither
2828 * tile. */
2829 map_distance_vector(&dx, &dy, src_tile, dst_tile);
2830 move_unit_map_canvas(punit, src_tile, dx, dy);
2831 }
2832 }
2833
2834 unit_tile_set(punit, dst_tile);
2835 unit_list_prepend(dst_tile->units, punit);
2836
2837 if (!unit_transported(punit)) {
2838 /* For find_visible_unit(), see above. */
2839 punit_moving = NULL;
2840
2841 refresh_unit_mapcanvas(punit, dst_tile, TRUE, FALSE);
2842 }
2843
2844 /* With the "full" city bar we have to update the city bar when units move
2845 * into or out of a city. For foreign cities this is handled separately,
2846 * via the occupied field of the short-city packet. */
2847 if (NULL != tile_city(src_tile)
2848 && can_player_see_units_in_city(client.conn.playing, tile_city(src_tile))) {
2849 update_city_description(tile_city(src_tile));
2850 }
2851 if (NULL != tile_city(dst_tile)
2852 && can_player_see_units_in_city(client.conn.playing, tile_city(dst_tile))) {
2853 update_city_description(tile_city(dst_tile));
2854 }
2855
2856 if (in_focus) {
2857 menus_update();
2858 }
2859}
2860
2861/**********************************************************************/
2865 static void do_unit_act_sel_vs(struct tile *ptile)
2866{
2867 unit_list_iterate(get_units_in_focus(), punit) {
2868 if (utype_may_act_at_all(unit_type_get(punit))) {
2869 /* Have the server record that an action decision is wanted for
2870 * this unit against this tile. */
2871 dsend_packet_unit_sscs_set(&client.conn, punit->id,
2872 USSDT_QUEUE, tile_index(ptile));
2873 }
2874 } unit_list_iterate_end;
2875}
2876
2877/**********************************************************************/
2880 void do_map_click(struct tile *ptile, enum quickselect_type qtype)
2881{
2882 struct city *pcity = tile_city(ptile);
2883 struct unit_list *punits = get_units_in_focus();
2884 bool maybe_goto = FALSE;
2885
2886 if (hover_state != HOVER_NONE) {
2887 switch (hover_state) {
2888 case HOVER_NONE:
2889 break;
2890 case HOVER_GOTO:
2891 do_unit_goto(ptile);
2892 break;
2893 case HOVER_TELEPORT:
2894 unit_list_iterate(punits, punit) {
2895 do_unit_teleport_to(punit, ptile);
2896 } unit_list_iterate_end;
2897 break;
2898 case HOVER_PARADROP:
2899 unit_list_iterate(punits, punit) {
2900 do_unit_paradrop_to(punit, ptile);
2901 } unit_list_iterate_end;
2902 break;
2903 case HOVER_CONNECT:
2904 do_unit_connect(ptile, connect_activity, connect_tgt);
2905 break;
2906 case HOVER_PATROL:
2907 do_unit_patrol_to(ptile);
2908 break;
2909 case HOVER_ACT_SEL_TGT:
2910 do_unit_act_sel_vs(ptile);
2911 break;
2912 case HOVER_GOTO_SEL_TGT:
2913 fc_assert(action_id_exists(goto_last_action));
2914 do_unit_goto(ptile);
2915 break;
2916 }
2917
2918 clear_hover_state();
2919 update_unit_info_label(get_units_in_focus());
2920 } else if (qtype != SELECT_POPUP && qtype != SELECT_APPEND) {
2921 /* Bypass stack or city popup if quickselect is specified. */
2922 struct unit *qunit = quickselect(ptile, qtype);
2923
2924 if (qunit) {
2925 unit_focus_set_and_select(qunit);
2926 maybe_goto = gui_options.keyboardless_goto;
2927 }
2928 } else if (NULL != pcity
2929 && can_player_see_city_internals(client.conn.playing, pcity)) {
2930 /* Otherwise use popups. */
2931 popup_city_dialog(pcity);
2932 } else if (unit_list_size(ptile->units) == 0
2933 && NULL == pcity
2934 && get_num_units_in_focus() > 0) {
2935 maybe_goto = gui_options.keyboardless_goto;
2936 } else if (unit_list_size(ptile->units) == 1
2937 && !get_transporter_occupancy(unit_list_get(ptile->units, 0))) {
2938 struct unit *punit = unit_list_get(ptile->units, 0);
2939
2940 if (unit_owner(punit) == client.conn.playing) {
2941 if (can_unit_do_activity_client(punit, ACTIVITY_IDLE)) {
2942 maybe_goto = gui_options.keyboardless_goto;
2943 if (qtype == SELECT_APPEND) {
2944 unit_focus_add(punit);
2945 } else {
2946 unit_focus_set_and_select(punit);
2947 }
2948 }
2949 } else if (pcity) {
2950 /* Don't hide the unit in the city. */
2951 unit_select_dialog_popup(ptile);
2952 }
2953 } else if (unit_list_size(ptile->units) > 0) {
2954 /* The stack list is always popped up, even if it includes enemy units.
2955 * If the server doesn't want the player to know about them it shouldn't
2956 * tell them! The previous behavior would only pop up the stack if you
2957 * owned a unit on the tile. This gave cheating clients an advantage,
2958 * and also showed you allied units if (and only if) you had a unit on
2959 * the tile (inconsistent). */
2960 unit_select_dialog_popup(ptile);
2961 }
2962
2963 /* See mapctrl_common.c */
2964 keyboardless_goto_start_tile = maybe_goto ? ptile : NULL;
2965 keyboardless_goto_button_down = maybe_goto;
2966 keyboardless_goto_active = FALSE;
2967}
2968
2969/**********************************************************************/
2974 static struct unit *quickselect(struct tile *ptile,
2975 enum quickselect_type qtype)
2976{
2977 int listsize = unit_list_size(ptile->units);
2978 struct unit *panytransporter = NULL,
2979 *panymovesea = NULL, *panysea = NULL,
2980 *panymoveland = NULL, *panyland = NULL,
2981 *panymoveunit = NULL, *panyunit = NULL;
2982
2983 fc_assert_ret_val(qtype > SELECT_POPUP, NULL);
2984
2985 if (qtype == SELECT_FOCUS) {
2986 return head_of_units_in_focus();
2987 }
2988
2989 if (listsize == 0) {
2990 return NULL;
2991 } else if (listsize == 1) {
2992 struct unit *punit = unit_list_get(ptile->units, 0);
2993 return (unit_owner(punit) == client.conn.playing) ? punit : NULL;
2994 }
2995
2996 /* Quickselect priorities. Units with moves left
2997 * before exhausted. Focus unit is excluded.
2998 *
2999 * SEA: Transporter
3000 * Sea unit
3001 * Any unit
3002 *
3003 * LAND: Military land unit
3004 * Non-combatant
3005 * Sea unit
3006 * Any unit
3007 */
3008
3009 unit_list_iterate(ptile->units, punit) {
3010 if (unit_owner(punit) != client.conn.playing || unit_is_in_focus(punit)) {
3011 continue;
3012 }
3013 if (qtype == SELECT_SEA) {
3014 /* Transporter. */
3015 if (get_transporter_capacity(punit)) {
3016 if (punit->moves_left > 0) {
3017 return punit;
3018 } else if (!panytransporter) {
3019 panytransporter = punit;
3020 }
3021 }
3022 /* Any sea, pref. moves left. */
3023 else if (utype_move_type(unit_type_get(punit)) == UMT_SEA) {
3024 if (punit->moves_left > 0) {
3025 if (!panymovesea) {
3026 panymovesea = punit;
3027 }
3028 } else if (!panysea) {
3029 panysea = punit;
3030 }
3031 }
3032 } else if (qtype == SELECT_LAND) {
3033 if (utype_move_type(unit_type_get(punit)) == UMT_LAND) {
3034 if (punit->moves_left > 0) {
3035 if (!is_special_unit(punit)) {
3036 return punit;
3037 } else if (!panymoveland) {
3038 panymoveland = punit;
3039 }
3040 } else if (!panyland) {
3041 panyland = punit;
3042 }
3043 }
3044 else if (utype_move_type(unit_type_get(punit)) == UMT_SEA) {
3045 if (punit->moves_left > 0) {
3046 panymovesea = punit;
3047 } else {
3048 panysea = punit;
3049 }
3050 }
3051 }
3052 if (punit->moves_left > 0 && !panymoveunit) {
3053 panymoveunit = punit;
3054 }
3055 if (!panyunit) {
3056 panyunit = punit;
3057 }
3058 } unit_list_iterate_end;
3059
3060 if (qtype == SELECT_SEA) {
3061 if (panytransporter) {
3062 return panytransporter;
3063 } else if (panymovesea) {
3064 return panymovesea;
3065 } else if (panysea) {
3066 return panysea;
3067 } else if (panymoveunit) {
3068 return panymoveunit;
3069 } else if (panyunit) {
3070 return panyunit;
3071 }
3072 }
3073 else if (qtype == SELECT_LAND) {
3074 if (panymoveland) {
3075 return panymoveland;
3076 } else if (panyland) {
3077 return panyland;
3078 } else if (panymovesea) {
3079 return panymovesea;
3080 } else if (panysea) {
3081 return panysea;
3082 } else if (panymoveunit) {
3083 return panymoveunit;
3084 } else if (panyunit) {
3085 return panyunit;
3086 }
3087 }
3088 return NULL;
3089}
3090
3091/**********************************************************************/
3095 void do_unit_goto(struct tile *ptile)
3096{
3097 fc_assert_ret(hover_state == HOVER_GOTO
3098 || hover_state == HOVER_GOTO_SEL_TGT);
3099 fc_assert_ret(goto_is_active());
3100
3101 if (hover_state == HOVER_GOTO_SEL_TGT) {
3102 send_goto_route();
3103 return;
3104 }
3105
3106 if (is_valid_goto_draw_line(ptile)) {
3107 send_goto_route();
3108 } else {
3109 create_event(ptile, E_BAD_COMMAND, ftc_client,
3110 _("Didn't find a route to the destination!"));
3111 }
3112}
3113
3114/**********************************************************************/
3117 static void do_unit_teleport_to(struct unit *punit, struct tile *ptile)
3118{
3119 struct action *teleport_action = NULL;
3120
3121 action_iterate(act_id) {
3122 struct action *paction = action_by_number(act_id);
3123
3124 if (!action_has_result(paction, ACTRES_TELEPORT)) {
3125 /* Not relevant. */
3126 continue;
3127 }
3128
3129 if (action_prob_possible(
3130 action_prob_unit_vs_tgt(paction, punit,
3131 tile_city(ptile), NULL,
3132 ptile, NULL))) {
3133 if (teleport_action == NULL) {
3134 /* This is the first possible teleport action. */
3135 teleport_action = paction;
3136 } else {
3137 /* More than one teleport action may be possible. The user must
3138 * choose. Have the server record that an action decision is wanted
3139 * for this unit so the dialog will be brought up. */
3140 dsend_packet_unit_sscs_set(&client.conn, punit->id,
3141 USSDT_QUEUE, tile_index(ptile));
3142 return;
3143 }
3144 }
3145 } action_iterate_end;
3146
3147 if (teleport_action != NULL) {
3148 request_do_action(teleport_action->id, punit->id,
3149 tile_index(ptile), 0 , "");
3150 }
3151}
3152
3153/**********************************************************************/
3156 void do_unit_paradrop_to(struct unit *punit, struct tile *ptile)
3157{
3158 struct action *paradrop_action = NULL;
3159
3160 action_iterate(act_id) {
3161 struct action *paction = action_by_number(act_id);
3162
3163 if (!(action_has_result(paction, ACTRES_PARADROP_CONQUER)
3164 || action_has_result(paction, ACTRES_PARADROP))) {
3165 /* Not relevant. */
3166 continue;
3167 }
3168
3169 if (action_prob_possible(
3170 action_prob_unit_vs_tgt(paction, punit,
3171 tile_city(ptile), NULL,
3172 ptile, NULL))) {
3173 if (paradrop_action == NULL) {
3174 /* This is the first possible paradrop action. */
3175 paradrop_action = paction;
3176 } else {
3177 /* More than one paradrop action may be possible. The user must
3178 * choose. Have the server record that an action decision is wanted
3179 * for this unit so the dialog will be brought up. */
3180 dsend_packet_unit_sscs_set(&client.conn, punit->id,
3181 USSDT_QUEUE, tile_index(ptile));
3182 return;
3183 }
3184 }
3185 } action_iterate_end;
3186
3187 if (paradrop_action != NULL) {
3188 request_do_action(paradrop_action->id, punit->id,
3189 tile_index(ptile), 0 , "");
3190 }
3191}
3192
3193/**********************************************************************/
3196 void do_unit_patrol_to(struct tile *ptile)
3197{
3198 if (is_valid_goto_draw_line(ptile)
3199 && !is_non_allied_unit_tile(ptile, client.conn.playing)) {
3200 send_patrol_route();
3201 } else {
3202 create_event(ptile, E_BAD_COMMAND, ftc_client,
3203 _("Didn't find a route to the destination!"));
3204 }
3205
3206 clear_hover_state();
3207}
3208
3209/**********************************************************************/
3212 void do_unit_connect(struct tile *ptile,
3213 enum unit_activity activity,
3214 struct extra_type *tgt)
3215{
3216 if (is_valid_goto_draw_line(ptile)) {
3217 send_connect_route(activity, tgt);
3218 } else {
3219 create_event(ptile, E_BAD_COMMAND, ftc_client,
3220 _("Didn't find a route to the destination!"));
3221 }
3222
3223 clear_hover_state();
3224}
3225
3226/**********************************************************************/
3229 void key_cancel_action(void)
3230{
3231 struct unit_list *punits = get_units_in_focus();
3232 cancel_tile_hiliting();
3233
3234 switch (hover_state) {
3235 case HOVER_GOTO_SEL_TGT:
3236 set_hover_state(punits, HOVER_GOTO, connect_activity, connect_tgt,
3237 goto_last_tgt, goto_last_sub_tgt,
3238 goto_last_action, goto_last_order);
3239 break;
3240 case HOVER_GOTO:
3241 case HOVER_PATROL:
3242 case HOVER_CONNECT:
3243 if (goto_pop_waypoint()) {
3244 break;
3245 }
3246 fc__fallthrough; /* else fall through: */
3247 case HOVER_TELEPORT:
3248 case HOVER_PARADROP:
3249 case HOVER_ACT_SEL_TGT:
3250 clear_hover_state();
3251 update_unit_info_label(get_units_in_focus());
3252
3253 keyboardless_goto_button_down = FALSE;
3254 keyboardless_goto_active = FALSE;
3255 keyboardless_goto_start_tile = NULL;
3256 break;
3257 case HOVER_NONE:
3258 break;
3259 };
3260}
3261
3262/**********************************************************************/
3266 void key_center_capital(void)
3267{
3268 struct city *capital = player_primary_capital(client_player());
3269
3270 if (capital) {
3271 /* Center on the tile, and pop up the crosshair overlay. */
3272 center_tile_mapcanvas(capital->tile);
3273 put_cross_overlay_tile(capital->tile);
3274 } else {
3275 create_event(NULL, E_BAD_COMMAND, ftc_client,
3276 _("Oh my! You seem to have no capital!"));
3277 }
3278}
3279
3280/**********************************************************************/
3283 void key_end_turn(void)
3284{
3285 send_turn_done();
3286}
3287
3288/**********************************************************************/
3291 void key_recall_previous_focus_unit(void)
3292{
3293 int i = 0;
3294
3295 /* Could use unit_list_copy here instead. Just having safe genlists
3296 * wouldn't be sufficient since we don't want to skip units already
3297 * removed from focus... */
3298 unit_list_iterate_safe(previous_focus, punit) {
3299 if (i == 0) {
3300 unit_focus_set(punit);
3301 } else {
3302 unit_focus_add(punit);
3303 }
3304 i++;
3305 } unit_list_iterate_safe_end;
3306}
3307
3308/**********************************************************************/
3312 void key_unit_move(enum direction8 gui_dir)
3313{
3314 unit_list_iterate(get_units_in_focus(), punit) {
3315 enum direction8 map_dir = gui_to_map_dir(gui_dir);
3316
3317 request_move_unit_direction(punit, map_dir);
3318 } unit_list_iterate_end;
3319}
3320
3321/**********************************************************************/
3324 void key_unit_build_city(void)
3325{
3326 unit_list_iterate(get_units_in_focus(), punit) {
3327 request_unit_build_city(punit);
3328 } unit_list_iterate_end;
3329}
3330
3331/**********************************************************************/
3334 void key_unit_build_wonder(void)
3335{
3336 unit_list_iterate(get_units_in_focus(), punit) {
3337 if (unit_can_do_action(punit, ACTION_HELP_WONDER)) {
3338 request_unit_caravan_action(punit, ACTION_HELP_WONDER);
3339 }
3340 } unit_list_iterate_end;
3341}
3342
3343/**********************************************************************/
3346 void key_unit_connect(enum unit_activity activity,
3347 struct extra_type *tgt)
3348{
3349 request_unit_connect(activity, tgt);
3350}
3351
3352/**********************************************************************/
3355 void key_unit_action_select(void)
3356{
3357 struct tile *ptile;
3358
3359 unit_list_iterate(get_units_in_focus(), punit) {
3360 if (utype_may_act_at_all(unit_type_get(punit))
3361 && (ptile = unit_tile(punit))) {
3362 /* Have the server record that an action decision is wanted for this
3363 * unit. */
3364 dsend_packet_unit_sscs_set(&client.conn, punit->id,
3365 USSDT_QUEUE, tile_index(ptile));
3366 }
3367 } unit_list_iterate_end;
3368}
3369
3370/**********************************************************************/
3377 void key_unit_action_select_tgt(void)
3378{
3379 struct unit_list *punits = get_units_in_focus();
3380
3381 if (hover_state == HOVER_ACT_SEL_TGT) {
3382 /* The 2nd key press means that the actor should target its own
3383 * tile. */
3384 key_unit_action_select();
3385
3386 /* Target tile selected. Clean up hover state. */
3387 clear_hover_state();
3388 update_unit_info_label(punits);
3389
3390 return;
3391 } else if (hover_state == HOVER_GOTO_SEL_TGT) {
3392 fc_assert(action_id_exists(goto_last_action));
3393
3394 /* We don't support long range actions in the middle of orders yet so
3395 * send it at once. */
3396 send_goto_route();
3397
3398 /* Target tile selected. Clean up hover state. */
3399 clear_hover_state();
3400 update_unit_info_label(punits);
3401
3402 return;
3403 } else if (hover_state == HOVER_GOTO
3404 && action_id_exists(goto_last_action)) {
3405 struct action *paction = action_by_number(goto_last_action);
3406
3407 create_event(unit_tile(unit_list_get(punits, 0)), E_BEGINNER_HELP,
3408 ftc_client,
3409 /* TRANS: Perform action inside a goto. */
3410 _("Click on a tile to do %s against it."),
3411 action_name_translation(paction));
3412
3413 set_hover_state(punits, HOVER_GOTO_SEL_TGT,
3414 connect_activity, connect_tgt,
3415 goto_last_tgt, goto_last_sub_tgt,
3416 goto_last_action, goto_last_order);
3417
3418 return;
3419 }
3420
3421 create_event(unit_tile(unit_list_get(punits, 0)), E_BEGINNER_HELP,
3422 ftc_client,
3423 /* TRANS: "Do..." action selection dialog target. */
3424 _("Click on a tile to act against it. "
3425 "Press 'd' again to act against own tile."));
3426
3427 set_hover_state(punits, HOVER_ACT_SEL_TGT, ACTIVITY_LAST, NULL,
3428 NO_TARGET, NO_TARGET, ACTION_NONE, ORDER_LAST);
3429}
3430
3431/**********************************************************************/
3434 void key_unit_done(void)
3435{
3436 request_unit_move_done();
3437}
3438
3439/**********************************************************************/
3442 void key_unit_goto(void)
3443{
3444 request_unit_goto(ORDER_LAST, ACTION_NONE, -1);
3445}
3446
3447/**********************************************************************/
3450 void key_unit_paradrop(void)
3451{
3452 request_unit_paradrop(get_units_in_focus());
3453}
3454
3455/**********************************************************************/
3458 void key_unit_patrol(void)
3459{
3460 request_unit_patrol();
3461}
3462
3463/**********************************************************************/
3466 void key_unit_teleport(void)
3467{
3468 request_unit_teleport(get_units_in_focus());
3469}
3470
3471/**********************************************************************/
3474 void key_unit_trade_route(void)
3475{
3476 unit_list_iterate(get_units_in_focus(), punit) {
3477 /* TODO: Is falling back on ACTION_MARKETPLACE if not able to establish
3478 * a trade route trade a good idea or an unplecant surprice? */
3479 if (unit_can_do_action(punit, ACTION_TRADE_ROUTE)) {
3480 request_unit_caravan_action(punit, ACTION_TRADE_ROUTE);
3481 }
3482 } unit_list_iterate_end;
3483}
3484
3485/**********************************************************************/
3488 void key_unit_unload_all(void)
3489{
3490 struct unit *pnext_focus = NULL, *plast;
3491
3492 unit_list_iterate(get_units_in_focus(), punit) {
3493 if ((plast = request_unit_unload_all(punit))) {
3494 pnext_focus = plast;
3495 }
3496 } unit_list_iterate_end;
3497
3498 if (pnext_focus) {
3499 unit_list_iterate(get_units_in_focus(), punit) {
3500 /* Unfocus the ships, and advance the focus to the last unloaded unit.
3501 * If there is no unit unloaded (which shouldn't happen, but could if
3502 * the caller doesn't check if the transporter is loaded), the we
3503 * don't do anything. */
3504 punit->client.focus_status = FOCUS_WAIT;
3505 } unit_list_iterate_end;
3506 unit_focus_set(pnext_focus);
3507 }
3508}
3509
3510/**********************************************************************/
3513 void key_unit_wait(void)
3514{
3515 request_units_wait(get_units_in_focus());
3516}
3517
3518/**********************************************************************/
3521 void key_unit_wakeup_others(void)
3522{
3523 unit_list_iterate(get_units_in_focus(), punit) {
3524 request_unit_wakeup(punit);
3525 } unit_list_iterate_end;
3526}
3527
3528/**********************************************************************/
3531 void key_unit_airbase(void)
3532{
3533 unit_list_iterate(get_units_in_focus(), punit) {
3534 struct base_type *pbase =
3535 get_base_by_gui_type(BASE_GUI_AIRBASE, punit, unit_tile(punit));
3536
3537 if (pbase) {
3538 struct extra_type *pextra = base_extra_get(pbase);
3539
3540 request_new_unit_activity_targeted(punit, ACTIVITY_BASE, pextra);
3541 }
3542 } unit_list_iterate_end;
3543}
3544
3545/**********************************************************************/
3548 void key_unit_auto_explore(void)
3549{
3550 unit_list_iterate(get_units_in_focus(), punit) {
3551 if (can_unit_do_activity_client(punit, ACTIVITY_EXPLORE)) {
3552 request_unit_ssa_set(punit, SSA_AUTOEXPLORE);
3553 }
3554 } unit_list_iterate_end;
3555}
3556
3557/**********************************************************************/
3561 void key_unit_auto_settle(void)
3562{
3563 unit_list_iterate(get_units_in_focus(), punit) {
3564 if (can_unit_do_autosettlers(punit)) {
3565 request_unit_autosettlers(punit);
3566 }
3567 } unit_list_iterate_end;
3568}
3569
3570/**********************************************************************/
3573 void key_unit_convert(void)
3574{
3575 unit_list_iterate(get_units_in_focus(), punit) {
3576 request_unit_convert(punit);
3577 } unit_list_iterate_end;
3578}
3579
3580/**********************************************************************/
3583 void key_unit_fortify(void)
3584{
3585 unit_list_iterate(get_units_in_focus(), punit) {
3586 if (can_unit_do_activity_client(punit, ACTIVITY_FORTIFYING)) {
3587 request_new_unit_activity(punit, ACTIVITY_FORTIFYING);
3588 }
3589 } unit_list_iterate_end;
3590}
3591
3592/**********************************************************************/
3595 void key_unit_fortress(void)
3596{
3597 unit_list_iterate(get_units_in_focus(), punit) {
3598 struct base_type *pbase =
3599 get_base_by_gui_type(BASE_GUI_FORTRESS, punit, unit_tile(punit));
3600
3601 if (pbase) {
3602 struct extra_type *pextra = base_extra_get(pbase);
3603
3604 request_new_unit_activity_targeted(punit, ACTIVITY_BASE, pextra);
3605 }
3606 } unit_list_iterate_end;
3607}
3608
3609/**********************************************************************/
3612 void key_unit_homecity(void)
3613{
3614 unit_list_iterate(get_units_in_focus(), punit) {
3615 request_unit_change_homecity(punit);
3616 } unit_list_iterate_end;
3617}
3618
3619/**********************************************************************/
3622 static void key_unit_extra(enum unit_activity act, enum extra_cause cause)
3623{
3624 unit_list_iterate(get_units_in_focus(), punit) {
3625 struct extra_type *tgt = next_extra_for_tile(unit_tile(punit),
3626 cause,
3627 unit_owner(punit),
3628 punit);
3629
3630 if (can_unit_do_activity_targeted_client(punit, act, tgt)) {
3631 request_new_unit_activity_targeted(punit, act, tgt);
3632 }
3633 } unit_list_iterate_end;
3634}
3635
3636/**********************************************************************/
3639 void key_unit_irrigate(void)
3640{
3641 key_unit_extra(ACTIVITY_IRRIGATE, EC_IRRIGATION);
3642}
3643
3644/**********************************************************************/
3647 void key_unit_cultivate(void)
3648{
3649 unit_list_iterate(get_units_in_focus(), punit) {
3650 if (can_unit_do_activity_client(punit, ACTIVITY_CULTIVATE)) {
3651 request_new_unit_activity(punit, ACTIVITY_CULTIVATE);
3652 }
3653 } unit_list_iterate_end;
3654}
3655
3656/**********************************************************************/
3659 void key_unit_mine(void)
3660{
3661 key_unit_extra(ACTIVITY_MINE, EC_MINE);
3662}
3663
3664/**********************************************************************/
3667 void key_unit_plant(void)
3668{
3669 unit_list_iterate(get_units_in_focus(), punit) {
3670 if (can_unit_do_activity_client(punit, ACTIVITY_PLANT)) {
3671 request_new_unit_activity(punit, ACTIVITY_PLANT);
3672 }
3673 } unit_list_iterate_end;
3674}
3675
3676/**********************************************************************/
3679 void key_unit_pillage(void)
3680{
3681 unit_list_iterate(get_units_in_focus(), punit) {
3682 if (can_unit_do_activity_client(punit, ACTIVITY_PILLAGE)) {
3683 request_unit_pillage(punit);
3684 }
3685 } unit_list_iterate_end;
3686}
3687
3688/**********************************************************************/
3691 void key_unit_clean(void)
3692{
3693 unit_list_iterate(get_units_in_focus(), punit) {
3694 struct extra_type *tgt = prev_extra_in_tile(unit_tile(punit),
3695 ERM_CLEAN,
3696 unit_owner(punit),
3697 punit);
3698
3699 if (tgt != NULL
3700 && can_unit_do_activity_targeted_client(punit, ACTIVITY_CLEAN, tgt)) {
3701 request_new_unit_activity_targeted(punit, ACTIVITY_CLEAN, tgt);
3702 }
3703 } unit_list_iterate_end;
3704}
3705
3706/**********************************************************************/
3709 void key_unit_road(void)
3710{
3711 unit_list_iterate(get_units_in_focus(), punit) {
3712 struct extra_type *tgt = next_extra_for_tile(unit_tile(punit),
3713 EC_ROAD,
3714 unit_owner(punit),
3715 punit);
3716
3717 if (tgt != NULL
3718 && can_unit_do_activity_targeted_client(punit, ACTIVITY_GEN_ROAD, tgt)) {
3719 request_new_unit_activity_targeted(punit, ACTIVITY_GEN_ROAD, tgt);
3720 }
3721 } unit_list_iterate_end;
3722}
3723
3724/**********************************************************************/
3727 void key_unit_sentry(void)
3728{
3729 unit_list_iterate(get_units_in_focus(), punit) {
3730 if (can_unit_do_activity_client(punit, ACTIVITY_SENTRY)) {
3731 request_new_unit_activity(punit, ACTIVITY_SENTRY);
3732 }
3733 } unit_list_iterate_end;
3734}
3735
3736/**********************************************************************/
3739 void key_unit_transform(void)
3740{
3741 unit_list_iterate(get_units_in_focus(), punit) {
3742 if (can_unit_do_activity_client(punit, ACTIVITY_TRANSFORM)) {
3743 request_new_unit_activity(punit, ACTIVITY_TRANSFORM);
3744 }
3745 } unit_list_iterate_end;
3746}
3747
3748/**********************************************************************/
3751 void key_unit_assign_battlegroup(int battlegroup, bool append)
3752{
3753 if (NULL != client.conn.playing && can_client_issue_orders()
3754 && battlegroups >= 0 && battlegroup < MAX_NUM_BATTLEGROUPS) {
3755 if (!append) {
3756 unit_list_iterate_safe(battlegroups[battlegroup], punit) {
3757 if (!unit_is_in_focus(punit)) {
3758 punit->battlegroup = BATTLEGROUP_NONE;
3759 dsend_packet_unit_sscs_set(&client.conn, punit->id,
3760 USSDT_BATTLE_GROUP,
3761 BATTLEGROUP_NONE);
3762 refresh_unit_mapcanvas(punit, unit_tile(punit), TRUE, FALSE);
3763 unit_list_remove(battlegroups[battlegroup], punit);
3764 }
3765 } unit_list_iterate_safe_end;
3766 }
3767 unit_list_iterate(get_units_in_focus(), punit) {
3768 if (punit->battlegroup != battlegroup) {
3769 if (punit->battlegroup >= 0
3770 && punit->battlegroup < MAX_NUM_BATTLEGROUPS) {
3771 unit_list_remove(battlegroups[punit->battlegroup], punit);
3772 }
3773 punit->battlegroup = battlegroup;
3774 dsend_packet_unit_sscs_set(&client.conn, punit->id,
3775 USSDT_BATTLE_GROUP,
3776 battlegroup);
3777 unit_list_append(battlegroups[battlegroup], punit);
3778 refresh_unit_mapcanvas(punit, unit_tile(punit), TRUE, FALSE);
3779 }
3780 } unit_list_iterate_end;
3781 unit_list_iterate(battlegroups[battlegroup], punit) {
3782 unit_focus_add(punit);
3783 } unit_list_iterate_end;
3784 }
3785}
3786
3787/**********************************************************************/
3790 void key_unit_select_battlegroup(int battlegroup, bool append)
3791{
3792 if (NULL != client.conn.playing && can_client_change_view()
3793 && battlegroups >= 0 && battlegroup < MAX_NUM_BATTLEGROUPS) {
3794 int i = 0;
3795
3796 if (unit_list_size(battlegroups[battlegroup]) == 0 && !append) {
3797 unit_focus_set(NULL);
3798 return;
3799 }
3800
3801 /* FIXME: this is very inefficient and can be improved. */
3802 unit_list_iterate(battlegroups[battlegroup], punit) {
3803 if (i == 0 && !append) {
3804 unit_focus_set(punit);
3805 } else {
3806 unit_focus_add(punit);
3807 }
3808 i++;
3809 } unit_list_iterate_end;
3810 }
3811}
3812
3813/**********************************************************************/
3816 void key_city_outlines_toggle(void)
3817{
3818 request_toggle_city_outlines();
3819}
3820
3821/**********************************************************************/
3824 void key_city_output_toggle(void)
3825{
3826 request_toggle_city_output();
3827}
3828
3829/**********************************************************************/
3832 void key_map_grid_toggle(void)
3833{
3834 request_toggle_map_grid();
3835}
3836
3837/**********************************************************************/
3840 void key_map_borders_toggle(void)
3841{
3842 request_toggle_map_borders();
3843}
3844
3845/**********************************************************************/
3848 void key_map_native_toggle(void)
3849{
3850 request_toggle_map_native();
3851}
3852
3853/**********************************************************************/
3856 void key_city_full_bar_toggle(void)
3857{
3858 request_toggle_city_full_bar();
3859}
3860
3861/**********************************************************************/
3864 void key_city_names_toggle(void)
3865{
3866 request_toggle_city_names();
3867}
3868
3869/**********************************************************************/
3873 void key_city_growth_toggle(void)
3874{
3875 request_toggle_city_growth();
3876}
3877
3878/**********************************************************************/
3882 void key_city_buycost_toggle(void)
3883{
3884 request_toggle_city_buycost();
3885}
3886
3887/**********************************************************************/
3890 void key_city_productions_toggle(void)
3891{
3892 request_toggle_city_productions();
3893}
3894
3895/**********************************************************************/
3899 void key_city_trade_routes_toggle(void)
3900{
3901 request_toggle_city_trade_routes();
3902}
3903
3904/**********************************************************************/
3907 void key_unit_stack_size_toggle(void)
3908{
3909 request_toggle_unit_stack_size();
3910}
3911
3912/**********************************************************************/
3915 void key_terrain_toggle(void)
3916{
3917 request_toggle_terrain();
3918}
3919
3920/**********************************************************************/
3923 void key_coastline_toggle(void)
3924{
3925 request_toggle_coastline();
3926}
3927
3928/**********************************************************************/
3931 void key_paths_toggle(void)
3932{
3933 request_toggle_paths();
3934}
3935
3936/**********************************************************************/
3939 void key_irrigation_toggle(void)
3940{
3941 request_toggle_irrigation();
3942}
3943
3944/**********************************************************************/
3947 void key_mines_toggle(void)
3948{
3949 request_toggle_mines();
3950}
3951
3952/**********************************************************************/
3955 void key_bases_toggle(void)
3956{
3957 request_toggle_bases();
3958}
3959
3960/**********************************************************************/
3963 void key_resources_toggle(void)
3964{
3965 request_toggle_resources();
3966}
3967
3968/**********************************************************************/
3971 void key_huts_toggle(void)
3972{
3973 request_toggle_huts();
3974}
3975
3976/**********************************************************************/
3979 void key_pollution_toggle(void)
3980{
3981 request_toggle_pollution();
3982}
3983
3984/**********************************************************************/
3987 void key_cities_toggle(void)
3988{
3989 request_toggle_cities();
3990}
3991
3992/**********************************************************************/
3995 void key_units_toggle(void)
3996{
3997 request_toggle_units();
3998}
3999
4000/**********************************************************************/
4003 void key_unit_solid_bg_toggle(void)
4004{
4005 request_toggle_unit_solid_bg();
4006}
4007
4008/**********************************************************************/
4011 void key_unit_shields_toggle(void)
4012{
4013 request_toggle_unit_shields();
4014}
4015
4016/**********************************************************************/
4019 void key_focus_unit_toggle(void)
4020{
4021 request_toggle_focus_unit();
4022}
4023
4024/**********************************************************************/
4027 void key_fog_of_war_toggle(void)
4028{
4029 request_toggle_fog_of_war();
4030}
4031
4032/**********************************************************************/
4035 void key_editor_toggle(void)
4036{
4037 dsend_packet_edit_mode(&client.conn, !game.info.is_edit_mode);
4038}
4039
4040/**********************************************************************/
4043 void key_editor_recalculate_borders(void)
4044{
4045 send_packet_edit_recalculate_borders(&client.conn);
4046}
4047
4048/**********************************************************************/
4052 void key_editor_toggle_fogofwar(void)
4053{
4054 if (client_has_player()) {
4055 dsend_packet_edit_toggle_fogofwar(&client.conn, client_player_number());
4056 }
4057}
4058
4059/**********************************************************************/
4062 void finish_city(struct tile *ptile, const char *name)
4063{
4064 unit_list_iterate(ptile->units, punit) {
4065 if (punit->client.asking_city_name) {
4066 /* Unit will disappear only in case city building still success.
4067 * Cancel city building status just in case something has changed
4068 * to prevent city building in the meanwhile and unit will remain
4069 * alive. */
4070 punit->client.asking_city_name = FALSE;
4071 request_do_action(ACTION_FOUND_CITY, punit->id, ptile->index,
4072 0, name);
4073 }
4074 } unit_list_iterate_end;
4075}
4076
4077/**********************************************************************/
4081 void cancel_city(struct tile *ptile)
4082{
4083 unit_list_iterate(ptile->units, punit) {
4084 punit->client.asking_city_name = FALSE;
4085 } unit_list_iterate_end;
4086}
action_name_translation
const char * action_name_translation(const struct action *action)
Definition actions.c:1982
action_id_name_translation
const char * action_id_name_translation(action_id act_id)
Definition actions.c:2002
action_prob_self
struct act_prob action_prob_self(const struct unit *actor_unit, const action_id act_id)
Definition actions.c:5497
action_prob_possible
bool action_prob_possible(const struct act_prob probability)
Definition actions.c:5823
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:5519
action_prob_vs_city
struct act_prob action_prob_vs_city(const struct unit *actor_unit, const action_id act_id, const struct city *target_city)
Definition actions.c:4981
action_prob_vs_unit
struct act_prob action_prob_vs_unit(const struct unit *actor_unit, const action_id act_id, const struct unit *target_unit)
Definition actions.c:5065
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:5342
action_prob_vs_stack
struct act_prob action_prob_vs_stack(const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile)
Definition actions.c:5258
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:5426
action_id_exists
bool action_id_exists(const action_id act_id)
Definition actions.c:1820
action_id_univs_not_blocking
#define action_id_univs_not_blocking(act_id, act_uni, tgt_uni)
Definition actions.h:927
action_by_result_iterate
#define action_by_result_iterate(_paction_, _result_)
Definition actions.h:479
action_by_number
static struct action * action_by_number(action_id act_id)
Definition actions.h:633
action_has_result
#define action_has_result(_act_, _res_)
Definition actions.h:429
action_id_get_role
#define action_id_get_role(act_id)
Definition actions.h:694
action_by_result_iterate_end
#define action_by_result_iterate_end
Definition actions.h:483
action_iterate_end
#define action_iterate_end
Definition actions.h:463
action_id
#define action_id(_act_)
Definition actions.h:659
action_iterate
#define action_iterate(_act_)
Definition actions.h:459
action_id_get_target_kind
#define action_id_get_target_kind(act_id)
Definition actions.h:650
action_id_has_result_safe
#define action_id_has_result_safe(act_id, result)
Definition actions.h:663
ACTION_NONE
#define ACTION_NONE
Definition actions.h:309
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, const char *const alt_tag2)
Definition audio.c:528
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:726
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:1353
send_turn_done
void send_turn_done(void)
Definition client_main.c:806
client
struct civclient client
Definition client_main.c:150
client_state
enum client_states client_state(void)
Definition client_main.c:1026
can_client_issue_orders
bool can_client_issue_orders(void)
Definition client_main.c:1264
client_has_player
bool client_has_player(void)
Definition client_main.c:1364
is_server_busy
bool is_server_busy(void)
Definition client_main.c:1337
can_client_change_view
bool can_client_change_view(void)
Definition client_main.c:1312
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:1081
can_units_do_connect
bool can_units_do_connect(struct unit_list *punits, enum unit_activity activity, struct extra_type *tgt)
Definition climisc.c:1230
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:311
combat.h
incite_cost
char * incite_cost
Definition comments.c:74
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:3923
key_irrigation_toggle
void key_irrigation_toggle(void)
Definition control.c:3939
request_toggle_huts
void request_toggle_huts(void)
Definition control.c:2616
key_unit_sentry
void key_unit_sentry(void)
Definition control.c:3727
request_toggle_city_outlines
void request_toggle_city_outlines(void)
Definition control.c:2369
key_unit_road
void key_unit_road(void)
Definition control.c:3709
request_unit_airlift
void request_unit_airlift(struct unit *punit, struct city *pcity)
Definition control.c:1517
do_move_unit
void do_move_unit(struct unit *punit, struct unit *target_unit)
Definition control.c:2773
request_toggle_resources
void request_toggle_resources(void)
Definition control.c:2603
request_toggle_city_names
void request_toggle_city_names(void)
Definition control.c:2447
key_recall_previous_focus_unit
void key_recall_previous_focus_unit(void)
Definition control.c:3291
request_unit_non_action_move
void request_unit_non_action_move(struct unit *punit, struct tile *dest_tile)
Definition control.c:1810
request_toggle_unit_stack_size
void request_toggle_unit_stack_size(void)
Definition control.c:2512
unit_is_in_focus
bool unit_is_in_focus(const struct unit *punit)
Definition control.c:383
key_city_output_toggle
void key_city_output_toggle(void)
Definition control.c:3824
request_toggle_focus_unit
void request_toggle_focus_unit(void)
Definition control.c:2694
request_toggle_city_output
void request_toggle_city_output(void)
Definition control.c:2382
request_unit_return
void request_unit_return(struct unit *punit)
Definition control.c:1526
request_unit_fortify
void request_unit_fortify(struct unit *punit)
Definition control.c:2324
key_unit_build_city
void key_unit_build_city(void)
Definition control.c:3324
key_editor_recalculate_borders
void key_editor_recalculate_borders(void)
Definition control.c:4043
request_unit_unload_all
struct unit * request_unit_unload_all(struct unit *punit)
Definition control.c:1485
request_unit_caravan_action
void request_unit_caravan_action(struct unit *punit, action_id action)
Definition control.c:2194
action_selection_no_longer_in_progress
void action_selection_no_longer_in_progress(const int old_actor_id)
Definition control.c:1033
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:2734
request_unit_wakeup
void request_unit_wakeup(struct unit *punit)
Definition control.c:1574
get_focus_unit_on_tile
struct unit * get_focus_unit_on_tile(const struct tile *ptile)
Definition control.c:391
key_focus_unit_toggle
void key_focus_unit_toggle(void)
Definition control.c:4019
request_toggle_map_grid
void request_toggle_map_grid(void)
Definition control.c:2395
action_decision_request
void action_decision_request(struct unit *actor_unit)
Definition control.c:1084
control_free
void control_free(void)
Definition control.c:154
request_toggle_mines
void request_toggle_mines(void)
Definition control.c:2577
set_units_in_combat
void set_units_in_combat(struct unit *pattacker, struct unit *pdefender)
Definition control.c:1014
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:1311
key_unit_action_select
void key_unit_action_select(void)
Definition control.c:3355
key_unit_auto_explore
void key_unit_auto_explore(void)
Definition control.c:3548
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:1943
key_cancel_action
void key_cancel_action(void)
Definition control.c:3229
request_toggle_city_buycost
void request_toggle_city_buycost(void)
Definition control.c:2486
key_unit_auto_settle
void key_unit_auto_settle(void)
Definition control.c:3561
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:2421
request_unit_patrol
void request_unit_patrol(void)
Definition control.c:2290
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:3346
key_city_full_bar_toggle
void key_city_full_bar_toggle(void)
Definition control.c:3856
request_unit_load
void request_unit_load(struct unit *pcargo, struct unit *ptrans, struct tile *ptile)
Definition control.c:2127
key_bases_toggle
void key_bases_toggle(void)
Definition control.c:3955
do_map_click
void do_map_click(struct tile *ptile, enum quickselect_type qtype)
Definition control.c:2880
key_unit_extra
static void key_unit_extra(enum unit_activity act, enum extra_cause cause)
Definition control.c:3622
key_map_native_toggle
void key_map_native_toggle(void)
Definition control.c:3848
request_toggle_map_borders
void request_toggle_map_borders(void)
Definition control.c:2408
key_resources_toggle
void key_resources_toggle(void)
Definition control.c:3963
request_unit_teleport
static void request_unit_teleport(struct unit_list *punits)
Definition control.c:2253
punit_attacking
static struct unit * punit_attacking
Definition control.c:105
unit_focus_add
void unit_focus_add(struct unit *punit)
Definition control.c:556
unit_focus_set
void unit_focus_set(struct unit *punit)
Definition control.c:501
do_unit_act_sel_vs
static void do_unit_act_sel_vs(struct tile *ptile)
Definition control.c:2865
request_unit_goto
void request_unit_goto(enum unit_orders last_order, action_id act_id, int sub_tgt_id)
Definition control.c:1104
do_unit_paradrop_to
void do_unit_paradrop_to(struct unit *punit, struct tile *ptile)
Definition control.c:3156
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:3450
can_units_attack_at
static bool can_units_attack_at(struct unit_list *punits, const struct tile *ptile)
Definition control.c:1171
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:1704
key_end_turn
void key_end_turn(void)
Definition control.c:3283
request_unit_disband
void request_unit_disband(struct unit *punit)
Definition control.c:2046
request_toggle_irrigation
void request_toggle_irrigation(void)
Definition control.c:2564
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:670
request_unit_autosettlers
void request_unit_autosettlers(const struct unit *punit)
Definition control.c:2112
request_unit_pillage
void request_unit_pillage(struct unit *punit)
Definition control.c:2335
key_unit_teleport
void key_unit_teleport(void)
Definition control.c:3466
request_center_focus_unit
void request_center_focus_unit(void)
Definition control.c:2721
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:4011
key_city_productions_toggle
void key_city_productions_toggle(void)
Definition control.c:3890
can_unit_do_connect
bool can_unit_do_connect(struct unit *punit, enum unit_activity activity, struct extra_type *tgt)
Definition control.c:1389
key_unit_build_wonder
void key_unit_build_wonder(void)
Definition control.c:3334
key_unit_plant
void key_unit_plant(void)
Definition control.c:3667
key_unit_fortress
void key_unit_fortress(void)
Definition control.c:3595
key_unit_mine
void key_unit_mine(void)
Definition control.c:3659
request_unit_change_homecity
void request_unit_change_homecity(struct unit *punit)
Definition control.c:2065
request_toggle_fog_of_war
void request_toggle_fog_of_war(void)
Definition control.c:2707
key_unit_pillage
void key_unit_pillage(void)
Definition control.c:3679
request_unit_unload
void request_unit_unload(struct unit *pcargo)
Definition control.c:2165
key_editor_toggle_fogofwar
void key_editor_toggle_fogofwar(void)
Definition control.c:4052
client_disband_unit_data_destroy
static void client_disband_unit_data_destroy(void *p)
Definition control.c:1933
request_unit_ssa_set
void request_unit_ssa_set(const struct unit *punit, enum server_side_agent agent)
Definition control.c:2099
find_best_focus_candidate
static struct unit * find_best_focus_candidate(bool accept_current)
Definition control.c:633
request_action_details
void request_action_details(action_id action, int actor_id, int target_id)
Definition control.c:1772
quickselect
static struct unit * quickselect(struct tile *ptile, enum quickselect_type qtype)
Definition control.c:2974
connect_activity
enum unit_activity connect_activity
Definition control.c:90
request_toggle_units
void request_toggle_units(void)
Definition control.c:2655
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:1912
update_unit_pix_label
void update_unit_pix_label(struct unit_list *punitlist)
Definition control.c:967
key_unit_irrigate
void key_unit_irrigate(void)
Definition control.c:3639
request_unit_build_city
void request_unit_build_city(struct unit *punit)
Definition control.c:1791
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:3488
key_cities_toggle
void key_cities_toggle(void)
Definition control.c:3987
key_unit_move
void key_unit_move(enum direction8 gui_dir)
Definition control.c:3312
key_city_outlines_toggle
void key_city_outlines_toggle(void)
Definition control.c:3816
key_unit_homecity
void key_unit_homecity(void)
Definition control.c:3612
request_unit_paradrop
void request_unit_paradrop(struct unit_list *punits)
Definition control.c:2217
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:3458
request_toggle_city_full_bar
void request_toggle_city_full_bar(void)
Definition control.c:2434
request_toggle_city_growth
void request_toggle_city_growth(void)
Definition control.c:2460
key_unit_solid_bg_toggle
void key_unit_solid_bg_toggle(void)
Definition control.c:4003
request_toggle_unit_solid_bg
void request_toggle_unit_solid_bg(void)
Definition control.c:2668
action_confirmation
void action_confirmation(struct act_confirmation_data *data, bool confirm)
Definition control.c:1740
key_terrain_toggle
void key_terrain_toggle(void)
Definition control.c:3915
key_paths_toggle
void key_paths_toggle(void)
Definition control.c:3931
request_unit_sentry
void request_unit_sentry(struct unit *punit)
Definition control.c:2313
key_unit_wakeup_others
void key_unit_wakeup_others(void)
Definition control.c:3521
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:413
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:3907
store_previous_focus
static void store_previous_focus(void)
Definition control.c:194
key_huts_toggle
void key_huts_toggle(void)
Definition control.c:3971
key_fog_of_war_toggle
void key_fog_of_war_toggle(void)
Definition control.c:4027
request_unit_connect
void request_unit_connect(enum unit_activity activity, struct extra_type *tgt)
Definition control.c:1456
clear_unit_orders
void clear_unit_orders(struct unit *punit)
Definition control.c:476
control_init
void control_init(void)
Definition control.c:137
request_toggle_terrain
void request_toggle_terrain(void)
Definition control.c:2525
action_decision_clear_want
void action_decision_clear_want(const int old_actor_id)
Definition control.c:1054
key_unit_wait
void key_unit_wait(void)
Definition control.c:3513
key_units_toggle
void key_units_toggle(void)
Definition control.c:3995
do_unit_connect
void do_unit_connect(struct tile *ptile, enum unit_activity activity, struct extra_type *tgt)
Definition control.c:3212
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:586
request_toggle_bases
void request_toggle_bases(void)
Definition control.c:2590
do_unit_patrol_to
void do_unit_patrol_to(struct tile *ptile)
Definition control.c:3196
key_unit_trade_route
void key_unit_trade_route(void)
Definition control.c:3474
request_toggle_coastline
void request_toggle_coastline(void)
Definition control.c:2538
key_unit_select_battlegroup
void key_unit_select_battlegroup(int battlegroup, bool append)
Definition control.c:3790
key_map_grid_toggle
void key_map_grid_toggle(void)
Definition control.c:3832
finish_city
void finish_city(struct tile *ptile, const char *name)
Definition control.c:4062
punit_moving
static struct unit * punit_moving
Definition control.c:102
key_pollution_toggle
void key_pollution_toggle(void)
Definition control.c:3979
head_of_units_in_focus
struct unit * head_of_units_in_focus(void)
Definition control.c:405
is_activity_on_tile
static bool is_activity_on_tile(struct tile *ptile, enum unit_activity activity)
Definition control.c:1295
find_visible_unit
struct unit * find_visible_unit(struct tile *ptile)
Definition control.c:804
can_be_irrigated
static bool can_be_irrigated(const struct tile *ptile, const struct unit *punit)
Definition control.c:1366
key_city_growth_toggle
void key_city_growth_toggle(void)
Definition control.c:3873
key_unit_action_select_tgt
void key_unit_action_select_tgt(void)
Definition control.c:3377
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:3882
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:3739
request_move_unit_direction
void request_move_unit_direction(struct unit *punit, int dir)
Definition control.c:1853
current_focus_append
static void current_focus_append(struct unit *punit)
Definition control.c:442
key_unit_done
void key_unit_done(void)
Definition control.c:3434
current_focus_remove
static void current_focus_remove(struct unit *punit)
Definition control.c:462
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:3899
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:2499
unit_focus_set_and_select
void unit_focus_set_and_select(struct unit *punit)
Definition control.c:620
request_unit_convert
void request_unit_convert(struct unit *punit)
Definition control.c:2089
request_toggle_paths
void request_toggle_paths(void)
Definition control.c:2551
request_toggle_unit_shields
void request_toggle_unit_shields(void)
Definition control.c:2681
key_city_names_toggle
void key_city_names_toggle(void)
Definition control.c:3864
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:1595
action_requires_confirmation
static bool action_requires_confirmation(action_id act, char *buf, size_t bufsize)
Definition control.c:1673
unit_focus_update
void unit_focus_update(void)
Definition control.c:771
key_unit_airbase
void key_unit_airbase(void)
Definition control.c:3531
key_unit_goto
void key_unit_goto(void)
Definition control.c:3442
control_mouse_cursor
void control_mouse_cursor(struct tile *ptile)
Definition control.c:1189
key_unit_convert
void key_unit_convert(void)
Definition control.c:3573
key_unit_clean
void key_unit_clean(void)
Definition control.c:3691
key_center_capital
void key_center_capital(void)
Definition control.c:3266
wakeup_sentried_units
void wakeup_sentried_units(struct tile *ptile)
Definition control.c:1557
request_toggle_cities
void request_toggle_cities(void)
Definition control.c:2642
key_unit_fortify
void key_unit_fortify(void)
Definition control.c:3583
key_editor_toggle
void key_editor_toggle(void)
Definition control.c:4035
key_unit_assign_battlegroup
void key_unit_assign_battlegroup(int battlegroup, bool append)
Definition control.c:3751
request_unit_move_done
void request_unit_move_done(void)
Definition control.c:2747
auto_center_on_focus_unit
void auto_center_on_focus_unit(void)
Definition control.c:429
key_unit_cultivate
void key_unit_cultivate(void)
Definition control.c:3647
blink_active_unit
double blink_active_unit(void)
Definition control.c:874
request_unit_upgrade
void request_unit_upgrade(struct unit *punit)
Definition control.c:2077
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:2473
cancel_city
void cancel_city(struct tile *ptile)
Definition control.c:4081
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:1903
request_toggle_pollution
void request_toggle_pollution(void)
Definition control.c:2629
goto_last_action
action_id goto_last_action
Definition control.c:93
key_mines_toggle
void key_mines_toggle(void)
Definition control.c:3947
do_unit_teleport_to
static void do_unit_teleport_to(struct unit *punit, struct tile *ptile)
Definition control.c:3117
do_unit_goto
void do_unit_goto(struct tile *ptile)
Definition control.c:3095
action_selection_next_in_focus
void action_selection_next_in_focus(const int old_actor_id)
Definition control.c:1066
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:3840
control.h
can_unit_do_activity_targeted_client
#define can_unit_do_activity_targeted_client(_punit_, _act_, _tgt_)
Definition control.h:43
MAX_NUM_UNITS_BELOW
#define MAX_NUM_UNITS_BELOW
Definition control.h:295
quickselect_type
quickselect_type
Definition control.h:37
SELECT_LAND
@ SELECT_LAND
Definition control.h:38
SELECT_APPEND
@ SELECT_APPEND
Definition control.h:38
SELECT_SEA
@ SELECT_SEA
Definition control.h:38
SELECT_POPUP
@ SELECT_POPUP
Definition control.h:38
SELECT_FOCUS
@ SELECT_FOCUS
Definition control.h:38
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:29
HOVER_TELEPORT
@ HOVER_TELEPORT
Definition control.h:28
HOVER_ACT_SEL_TGT
@ HOVER_ACT_SEL_TGT
Definition control.h:32
HOVER_NONE
@ HOVER_NONE
Definition control.h:26
HOVER_CONNECT
@ HOVER_CONNECT
Definition control.h:30
HOVER_PATROL
@ HOVER_PATROL
Definition control.h:31
HOVER_GOTO_SEL_TGT
@ HOVER_GOTO_SEL_TGT
Definition control.h:33
can_unit_do_activity_client
#define can_unit_do_activity_client(_punit_, _act_)
Definition control.h:41
dialogs_g.h
target_unit
struct unit struct city struct unit * target_unit
Definition dialogs_g.h:56
actor_unit
struct unit * actor_unit
Definition dialogs_g.h:55
action_selection_no_longer_in_progress_gui_specific
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs action_selection_no_longer_in_progress_gui_specific
Definition dialogs_g.h:69
punit
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:74
target_city
struct unit struct city * target_city
Definition dialogs_g.h:56
editor.h
get_unit_bonus
int get_unit_bonus(const struct unit *punit, enum effect_type effect_type)
Definition effects.c:1070
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:765
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:790
can_build_extra
bool can_build_extra(const struct extra_type *pextra, const struct unit *punit, const struct tile *ptile)
Definition extras.c:533
extra_type_iterate
#define extra_type_iterate(_p)
Definition extras.h:315
extra_deps_iterate
#define extra_deps_iterate(_reqs, _dep)
Definition extras.h:371
extra_type_iterate_end
#define extra_type_iterate_end
Definition extras.h:321
is_extra_caused_by
#define is_extra_caused_by(e, c)
Definition extras.h:203
extra_index
#define extra_index(_e_)
Definition extras.h:183
extra_deps_iterate_end
#define extra_deps_iterate_end
Definition extras.h:379
EXTRA_NONE
#define EXTRA_NONE
Definition extras.h:85
extra_road_get
#define extra_road_get(_e_)
Definition extras.h:191
NO_TARGET
#define NO_TARGET
Definition fc_types.h:357
RPT_POSSIBLE
@ RPT_POSSIBLE
Definition fc_types.h:703
DIR8_ORIGIN
#define DIR8_ORIGIN
Definition fc_types.h:460
action_id
int action_id
Definition fc_types.h:392
MAX_EXTRA_TYPES
#define MAX_EXTRA_TYPES
Definition fc_types.h:50
IDENTITY_NUMBER_ZERO
#define IDENTITY_NUMBER_ZERO
Definition fc_types.h:92
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:62
is_player_phase
bool is_player_phase(const struct player *pplayer, int phase)
Definition game.c:705
wld
struct world wld
Definition game.c:63
game_unit_by_number
struct unit * game_unit_by_number(int id)
Definition game.c:116
game.h
exit_goto_state
void exit_goto_state(void)
Definition goto.c:1022
goto_is_active
bool goto_is_active(void)
Definition goto.c:1059
path_to_nearest_allied_city
struct pf_path * path_to_nearest_allied_city(struct unit *punit)
Definition goto.c:1982
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:1338
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:1040
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:1001
send_goto_route
void send_goto_route(void)
Definition goto.c:1869
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:1363
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:1583
action_selection_close
void action_selection_close(void)
Definition action_dialog.c:1732
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:377
popup_pillage_dialog
void popup_pillage_dialog(struct unit *punit, bv_extras extras)
Definition dialogs.c:338
request_action_confirmation
void request_action_confirmation(const char *expl, struct act_confirmation_data *data)
Definition dialogs.c:1607
real_focus_units_changed
void real_focus_units_changed(void)
Definition gui_main.c:2171
set_unit_icons_more_arrow
void set_unit_icons_more_arrow(bool onoff)
Definition gui_main.c:2148
set_unit_icon
void set_unit_icon(int idx, struct unit *punit)
Definition gui_main.c:2118
create_line_at_mouse_pos
void create_line_at_mouse_pos(void)
Definition mapctrl.c:355
update_turn_done_button
void update_turn_done_button(bool do_restore)
Definition mapview.c:76
put_cross_overlay_tile
void put_cross_overlay_tile(struct tile *ptile)
Definition mapview.c:643
update_unit_info_label
void update_unit_info_label(struct unit_list *punits)
Definition mapview.c:275
update_mouse_cursor
void update_mouse_cursor(enum cursor_type new_cursor_type)
Definition mapview.c:257
request_transport
bool request_transport(struct unit *cargo, struct tile *ptile)
Definition transportdlg.c:82
mouse_cursor_type
enum cursor_type mouse_cursor_type
Definition gui_mouse.c:46
gui_main_g.h
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:1347
is_tiles_adjacent
bool is_tiles_adjacent(const struct tile *tile0, const struct tile *tile1)
Definition map.c:931
same_pos
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Definition map.c:940
mapstep
struct tile * mapstep(const struct civ_map *nmap, const struct tile *ptile, enum direction8 dir)
Definition map.c:371
map_distance_vector
void map_distance_vector(int *dx, int *dy, const struct tile *tile0, const struct tile *tile1)
Definition map.c:1073
map.h
iterate_outward
#define iterate_outward(nmap, start_tile, max_dist, itr_tile)
Definition map.h:367
iterate_outward_end
#define iterate_outward_end
Definition map.h:371
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:1860
get_center_tile_mapcanvas
struct tile * get_center_tile_mapcanvas(void)
Definition mapview_common.c:1227
move_unit_map_canvas
void move_unit_map_canvas(struct unit *punit, struct tile *src_tile, int dx, int dy)
Definition mapview_common.c:2700
center_tile_mapcanvas
void center_tile_mapcanvas(const struct tile *ptile)
Definition mapview_common.c:1237
update_city_description
void update_city_description(struct city *pcity)
Definition mapview_common.c:1880
refresh_unit_mapcanvas
void refresh_unit_mapcanvas(struct unit *punit, struct tile *ptile, bool full_refresh, bool write_to_screen)
Definition mapview_common.c:520
tile_visible_and_not_on_border_mapcanvas
bool tile_visible_and_not_on_border_mapcanvas(struct tile *ptile)
Definition mapview_common.c:1282
mapview_g.h
mem.h
fc_strdup
#define fc_strdup(str)
Definition mem.h:43
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:319
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:491
movement.h
server_optset
const struct option_set * server_optset
Definition options.c:4019
option_bool_get
bool option_bool_get(const struct option *poption)
Definition options.c:796
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:430
options.h
refresh_overview_canvas
void refresh_overview_canvas(void)
Definition overview_common.c:376
overview_common.h
REQEST_PLAYER_INITIATED
#define REQEST_PLAYER_INITIATED
Definition packets.h:63
dsend_packet_unit_change_activity
int dsend_packet_unit_change_activity(struct connection *pc, int unit_id, enum unit_activity activity, int target)
Definition packets_gen.c:33614
dsend_packet_unit_do_action
int dsend_packet_unit_do_action(struct connection *pc, int actor_id, int target_id, int sub_tgt_id, const char *name, action_id action_type)
Definition packets_gen.c:32152
send_packet_unit_orders
int send_packet_unit_orders(struct connection *pc, const struct packet_unit_orders *packet)
Definition packets_gen.c:31093
dsend_packet_unit_get_actions
int dsend_packet_unit_get_actions(struct connection *pc, int actor_unit_id, int target_unit_id, int target_tile_id, int target_extra_id, int request_kind)
Definition packets_gen.c:32832
dsend_packet_unit_server_side_agent_set
int dsend_packet_unit_server_side_agent_set(struct connection *pc, int unit_id, enum server_side_agent agent)
Definition packets_gen.c:31320
send_packet_edit_recalculate_borders
int send_packet_edit_recalculate_borders(struct connection *pc)
Definition packets_gen.c:75129
dsend_packet_unit_action_query
int dsend_packet_unit_action_query(struct connection *pc, int actor_id, int target_id, action_id action_type, int request_kind)
Definition packets_gen.c:31623
dsend_packet_city_name_suggestion_req
int dsend_packet_city_name_suggestion_req(struct connection *pc, int unit_id)
Definition packets_gen.c:20312
dsend_packet_edit_toggle_fogofwar
int dsend_packet_edit_toggle_fogofwar(struct connection *pc, int player)
Definition packets_gen.c:75337
dsend_packet_unit_sscs_set
int dsend_packet_unit_sscs_set(struct connection *pc, int unit_id, enum unit_ss_data_type type, int value)
Definition packets_gen.c:30632
dsend_packet_edit_mode
int dsend_packet_edit_mode(struct connection *pc, bool state)
Definition packets_gen.c:75102
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:1229
player_primary_capital
struct city * player_primary_capital(const struct player *pplayer)
Definition player.c:1337
can_player_see_units_in_city
bool can_player_see_units_in_city(const struct player *pplayer, const struct city *pcity)
Definition player.c:1133
can_player_see_city_internals
bool can_player_see_city_internals(const struct player *pplayer, const struct city *pcity)
Definition player.c:1149
players_iterate_alive_end
#define players_iterate_alive_end
Definition player.h:547
players_iterate_alive
#define players_iterate_alive(_pplayer)
Definition player.h:542
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:5505
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
act_confirmation_data
Definition control.h:145
act_confirmation_data::act
action_id act
Definition control.h:146
act_confirmation_data::tgt_sub
int tgt_sub
Definition control.h:149
act_confirmation_data::name
char * name
Definition control.h:150
act_confirmation_data::target
int target
Definition control.h:148
act_confirmation_data::actor
int actor
Definition control.h:147
action
Definition actions.h:360
agent
Definition agents.h:40
astring
Definition astring.h:36
base_type
Definition base.h:41
city
Definition city.h:320
city::id
int id
Definition city.h:326
city::capital
enum capital_type capital
Definition city.h:328
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:215
client_options::enable_cursor_changes
bool enable_cursor_changes
Definition options.h:173
client_options::auto_turn_done
bool auto_turn_done
Definition options.h:164
client_options::draw_specials
bool draw_specials
Definition options.h:207
client_options::draw_city_output
bool draw_city_output
Definition options.h:194
client_options::draw_city_names
bool draw_city_names
Definition options.h:196
client_options::draw_city_productions
bool draw_city_productions
Definition options.h:198
client_options::smooth_move_unit_msec
int smooth_move_unit_msec
Definition options.h:151
client_options::draw_mines
bool draw_mines
Definition options.h:205
client_options::draw_borders
bool draw_borders
Definition options.h:214
client_options::draw_fortress_airbase
bool draw_fortress_airbase
Definition options.h:206
client_options::draw_city_buycost
bool draw_city_buycost
Definition options.h:199
client_options::draw_unit_stack_size
bool draw_unit_stack_size
Definition options.h:218
client_options::draw_irrigation
bool draw_irrigation
Definition options.h:204
client_options::draw_terrain
bool draw_terrain
Definition options.h:201
client_options::draw_units
bool draw_units
Definition options.h:211
client_options::auto_center_on_automated
bool auto_center_on_automated
Definition options.h:156
client_options::draw_fog_of_war
bool draw_fog_of_war
Definition options.h:213
client_options::draw_city_trade_routes
bool draw_city_trade_routes
Definition options.h:200
client_options::unit_selection_clears_orders
bool unit_selection_clears_orders
Definition options.h:175
client_options::draw_unit_shields
bool draw_unit_shields
Definition options.h:217
client_options::draw_cities
bool draw_cities
Definition options.h:210
client_options::draw_map_grid
bool draw_map_grid
Definition options.h:195
client_options::draw_city_growth
bool draw_city_growth
Definition options.h:197
client_options::draw_huts
bool draw_huts
Definition options.h:208
client_options::draw_focus_unit
bool draw_focus_unit
Definition options.h:212
client_options::draw_paths
bool draw_paths
Definition options.h:203
client_options::draw_city_outlines
bool draw_city_outlines
Definition options.h:193
client_options::draw_coastline
bool draw_coastline
Definition options.h:202
client_options::popup_actor_arrival
bool popup_actor_arrival
Definition options.h:168
client_options::draw_full_citybar
bool draw_full_citybar
Definition options.h:216
client_options::draw_pollution
bool draw_pollution
Definition options.h:209
client_options::auto_center_on_unit
bool auto_center_on_unit
Definition options.h:155
client_options::solid_color_behind_units
bool solid_color_behind_units
Definition options.h:149
client_options::popup_last_move_to_allied
bool popup_last_move_to_allied
Definition options.h:170
client_options::keyboardless_goto
bool keyboardless_goto
Definition options.h:172
connection::playing
struct player * playing
Definition connection.h:151
connection::client
struct connection::@58::@63 client
connection::last_request_id_used
int last_request_id_used
Definition connection.h:187
connection::id
int id
Definition connection.h:137
extra_type
Definition extras.h:88
extra_type::reqs
struct requirement_vector reqs
Definition extras.h:106
option
Definition options.c:478
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:705
packet_unit_orders::src_tile
int src_tile
Definition packets_gen.h:707
packet_unit_orders::length
int length
Definition packets_gen.h:708
packet_unit_orders::unit_id
int unit_id
Definition packets_gen.h:706
packet_unit_orders::dest_tile
int dest_tile
Definition packets_gen.h:712
packet_unit_orders::repeat
bool repeat
Definition packets_gen.h:709
packet_unit_orders::vigilant
bool vigilant
Definition packets_gen.h:710
packet_unit_orders::orders
struct unit_order orders[MAX_LEN_ROUTE]
Definition packets_gen.h:711
pf_path
Definition path_finding.h:344
pf_position::turn
int turn
Definition path_finding.h:329
player
Definition player.h:247
player::units
struct unit_list * units
Definition player.h:280
player::is_alive
bool is_alive
Definition player.h:266
player::phase_done
bool phase_done
Definition player.h:261
req_context
Definition requirements.h:100
req_context::activity
enum unit_activity activity
Definition requirements.h:113
req_context::unit
const struct unit * unit
Definition requirements.h:106
road_type
Definition road.h:71
terrain
Definition terrain.h:182
tile
Definition tile.h:50
tile::index
int index
Definition tile.h:51
tile::units
struct unit_list * units
Definition tile.h:58
tileset
Definition tilespec.c:481
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:524
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::client
struct unit::@81::@83 client
unit::id
int id
Definition unit.h:145
unit::hp
int hp
Definition unit.h:151
unit::asking_city_name
bool asking_city_name
Definition unit.h:225
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:214
unit::ssa_controller
enum server_side_agent ssa_controller
Definition unit.h:172
universal
Definition fc_types.h:901
universal::kind
enum universals_n kind
Definition fc_types.h:903
world::map
struct civ_map map
Definition world_object.h:38
fc_snprintf
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:974
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
fc__fallthrough
#define fc__fallthrough
Definition support.h:119
get_preferred_pillage
struct extra_type * get_preferred_pillage(bv_extras extras)
Definition terrain.c:550
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:699
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:955
tile_virtual_destroy
void tile_virtual_destroy(struct tile *vtile)
Definition tile.c:1033
tile_has_road
bool tile_has_road(const struct tile *ptile, const struct road_type *proad)
Definition tile.c:844
tile_virtual_new
struct tile * tile_virtual_new(const struct tile *ptile)
Definition tile.c:981
tile_city
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
tile_index
#define tile_index(_pt_)
Definition tile.h:88
tile_hash_iterate
#define tile_hash_iterate(hash, ptile)
Definition tile.h:82
tile_terrain
#define tile_terrain(_tile)
Definition tile.h:110
tile_hash_iterate_end
#define tile_hash_iterate_end
Definition tile.h:84
tile_continent
#define tile_continent(_tile)
Definition tile.h:92
tile_has_extra
#define tile_has_extra(ptile, pextra)
Definition tile.h:147
get_focus_unit_toggle_timeout
double get_focus_unit_toggle_timeout(const struct tileset *t)
Definition tilespec.c:6523
toggle_focus_unit_state
void toggle_focus_unit_state(struct tileset *t)
Definition tilespec.c:6555
focus_unit_in_combat
void focus_unit_in_combat(struct tileset *t)
Definition tilespec.c:6544
tilespec.h
cursor_type
cursor_type
Definition tilespec.h:287
CURSOR_TELEPORT
@ CURSOR_TELEPORT
Definition tilespec.h:291
CURSOR_GOTO
@ CURSOR_GOTO
Definition tilespec.h:288
CURSOR_INVALID
@ CURSOR_INVALID
Definition tilespec.h:294
CURSOR_PATROL
@ CURSOR_PATROL
Definition tilespec.h:289
CURSOR_WAIT
@ CURSOR_WAIT
Definition tilespec.h:298
CURSOR_SELECT
@ CURSOR_SELECT
Definition tilespec.h:293
CURSOR_DEFAULT
@ CURSOR_DEFAULT
Definition tilespec.h:300
CURSOR_PARADROP
@ CURSOR_PARADROP
Definition tilespec.h:290
CURSOR_NUKE
@ CURSOR_NUKE
Definition tilespec.h:292
CURSOR_ATTACK
@ CURSOR_ATTACK
Definition tilespec.h:295
timer_start
void timer_start(struct timer *t)
Definition timing.c:264
timer_read_seconds
double timer_read_seconds(struct timer *t)
Definition timing.c:384
timer_renew
struct timer * timer_renew(struct timer *t, enum timer_timetype type, enum timer_use use, const char *name)
Definition timing.c:180
timing.h
TIMER_ACTIVE
@ TIMER_ACTIVE
Definition timing.h:46
TIMER_USER
@ TIMER_USER
Definition timing.h:42
get_transporter_occupancy
int get_transporter_occupancy(const struct unit *ptrans)
Definition unit.c:1779
is_attack_unit
bool is_attack_unit(const struct unit *punit)
Definition unit.c:307
unit_transport_get
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2437
could_unit_load
bool could_unit_load(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:696
can_unit_do_autosettlers
bool can_unit_do_autosettlers(const struct unit *punit)
Definition unit.c:602
unit_can_do_action
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:361
can_unit_teleport
bool can_unit_teleport(const struct civ_map *nmap, const struct unit *punit)
Definition unit.c:803
get_transporter_capacity
int get_transporter_capacity(const struct unit *punit)
Definition unit.c:299
can_unit_paradrop
bool can_unit_paradrop(const struct civ_map *nmap, const struct unit *punit)
Definition unit.c:819
is_special_unit
bool is_special_unit(const struct unit *punit)
Definition unit.c:352
unit_tile_set
void unit_tile_set(struct unit *punit, struct tile *ptile)
Definition unit.c:1252
unit_transported
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2421
can_unit_unload
bool can_unit_unload(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:748
unit_has_orders
bool unit_has_orders(const struct unit *punit)
Definition unit.c:205
transporter_for_unit
struct unit * transporter_for_unit(const struct unit *pcargo)
Definition unit.c:1908
unit_tile
#define unit_tile(_pu)
Definition unit.h:390
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:389
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:425
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:1569
utype_move_type
enum unit_move_type utype_move_type(const struct unit_type *punittype)
Definition unittype.c:1551
utype_may_act_at_all
bool utype_may_act_at_all(const struct unit_type *putype)
Definition unittype.c:359
unit_class_get
struct unit_class * unit_class_get(const struct unit *punit)
Definition unittype.c:2498
unit_has_type_flag
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:190
role_units_translations
bool role_units_translations(struct astring *astr, int flag, bool alts)
Definition unittype.c:1668
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