Freeciv-3.3
Loading...
Searching...
No Matches
goto.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#include <string.h>
19
20/* utility */
21#include "log.h"
22#include "mem.h"
23
24/* common */
25#include "game.h"
26#include "map.h"
27#include "movement.h"
28#include "packets.h"
29#include "pf_tools.h"
30#include "road.h"
31#include "unit.h"
32#include "unitlist.h"
33
34/* client/include */
35#include "client_main.h"
36#include "control.h"
37#include "mapview_g.h"
38
39/* client */
40#include "goto.h"
41#include "mapctrl_common.h"
42
43#define LOG_GOTO_PATH LOG_DEBUG
44#define log_goto_path log_debug
45#define log_goto_packet log_debug
46
47/*
48 * The whole path is separated by waypoints into parts. Each part has its
49 * own starting position and requires its own map. When the unit is unable
50 * to move, end_tile equals start_tile and path is NULL.
51 */
52struct part {
55 struct pf_path *path;
56 struct pf_map *map;
57};
58
59struct goto_map {
60 struct unit *focus;
61 struct part *parts;
63 union {
64 struct {
66 } connect;
67 struct {
69 } patrol;
70 };
72};
73
74/* get 'struct goto_map_list' and related functions: */
75#define SPECLIST_TAG goto_map
76#define SPECLIST_TYPE struct goto_map
77#include "speclist.h"
78#define goto_map_list_iterate(gotolist, pgoto) \
79 TYPED_LIST_ITERATE(struct goto_map, gotolist, pgoto)
80#define goto_map_list_iterate_end \
81 LIST_ITERATE_END
82
83/* Iterate over goto maps, assumes no dead units. */
84#define goto_map_unit_iterate(gotolist, pgoto, punit) \
85 goto_map_list_iterate(gotolist, pgoto) { \
86 struct unit *punit = goto_map_unit(pgoto);
87
88#define goto_map_unit_iterate_end \
89 } goto_map_list_iterate_end;
90
91static struct goto_map_list *goto_maps = NULL;
92static bool goto_warned = FALSE;
93
94static void reset_last_part(struct goto_map *goto_map);
95static void remove_last_part(struct goto_map *goto_map);
96static void fill_parameter_part(struct pf_parameter *param,
97 const struct goto_map *goto_map,
98 const struct part *p);
99
100/****************************************************************************
101 Various stuff for the goto routes
102****************************************************************************/
103static struct tile *goto_destination = NULL;
104
105/************************************************************************/
108static struct goto_map *goto_map_new(struct unit *punit)
109{
110 struct goto_map *goto_map = fc_malloc(sizeof(*goto_map));
111
114 goto_map->num_parts = 0;
115
116 return goto_map;
117}
118
119/************************************************************************/
122static void goto_map_free(struct goto_map *goto_map)
123{
124 if (NULL != goto_map->parts) {
125 while (goto_map->num_parts > 0) {
127 }
129 }
132 }
133 free(goto_map);
134}
135
136/************************************************************************/
139static struct unit *goto_map_unit(const struct goto_map *goto_map)
140{
141 struct unit *punit = goto_map->focus;
142
143 fc_assert(punit != NULL);
146
147 return punit;
148}
149
150/************************************************************************/
154{
156
158}
159
160/************************************************************************/
176
177/************************************************************************/
180bool is_valid_goto_destination(const struct tile *ptile)
181{
182 return (NULL != goto_destination && ptile == goto_destination);
183}
184
185/************************************************************************/
188static void goto_path_redraw(const struct pf_path *new_path,
189 const struct pf_path *old_path)
190{
191 int start_index = 0;
192 int i;
193
195
196 if (old_path != NULL) {
197 /* We had a path drawn already. Determine how much of it we can reuse
198 * in drawing the new path. */
199 for (i = 0; i < new_path->length - 1 && i < old_path->length - 1; i++) {
200 struct pf_position *old_pos = old_path->positions + i;
201 struct pf_position *new_pos = new_path->positions + i;
202
203 if (old_pos->dir_to_next_pos != new_pos->dir_to_next_pos
204 || old_pos->tile != new_pos->tile) {
205 break;
206 }
207 }
208 start_index = i;
209
210 /* Erase everything we cannot reuse. */
211 for (; i < old_path->length - 1; i++) {
212 struct pf_position *pos = old_path->positions + i;
213
214 if (is_valid_dir(pos->dir_to_next_pos)) {
215 mapdeco_remove_gotoline(pos->tile, pos->dir_to_next_pos);
216 } else {
217 fc_assert(pos->tile == (pos + 1)->tile);
218 }
219 }
220 }
221
222 /* Draw the new path. */
223 for (i = start_index; i < new_path->length - 1; i++) {
224 struct pf_position *pos = new_path->positions + i;
225
226 if (is_valid_dir(pos->dir_to_next_pos)) {
227 mapdeco_add_gotoline(pos->tile, pos->dir_to_next_pos);
228 } else {
229 fc_assert(pos->tile == (pos + 1)->tile);
230 }
231 }
232}
233
234/************************************************************************/
237static void goto_path_undraw(const struct pf_path *path)
238{
239 int i;
240
241 fc_assert_ret(path != NULL);
242
243 for (i = 0; i < path->length - 1; i++) {
244 struct pf_position *pos = path->positions + i;
245
246 if (is_valid_dir(pos->dir_to_next_pos)) {
247 mapdeco_remove_gotoline(pos->tile, pos->dir_to_next_pos);
248 } else {
249 fc_assert(pos->tile == (pos + 1)->tile);
250 }
251 }
252}
253
254/************************************************************************/
260 struct tile *ptile)
261{
262 struct pf_path *old_path, *new_path;
263 struct part *p = &goto_map->parts[goto_map->num_parts - 1];
264
265 old_path = p->path;
266 if (old_path != NULL && pf_path_last_position(old_path)->tile == ptile) {
267 /* Nothing to update. */
268 return TRUE;
269 }
270
271 log_debug("update_last_part(%d,%d) old (%d,%d)-(%d,%d)",
272 TILE_XY(ptile), TILE_XY(p->start_tile), TILE_XY(p->end_tile));
273 new_path = pf_map_path(p->map, ptile);
274
275 if (!new_path) {
276 log_goto_path(" no path found");
277
278 if (p->start_tile == ptile) {
279 /* This mean we cannot reach the start point. It is probably,
280 * a path-finding bug, but don't make infinite recursion. */
281
282 if (!goto_warned) {
283 log_error("No path found to reach the start point.");
285 }
286
287 if (old_path != NULL) {
290 p->path = NULL;
291 }
297 }
298 return FALSE;
299 }
300
302 return FALSE;
303 }
304
305 log_goto_path(" path found:");
307
308 p->path = new_path;
309 p->end_tile = ptile;
312
313 if (hover_state == HOVER_PATROL) {
314 struct pf_parameter parameter;
315 struct pf_map *pfm;
316 struct pf_path *return_path;
317
318 fill_parameter_part(&parameter, goto_map, p);
319 pfm = pf_map_new(&parameter);
320 return_path = pf_map_path(pfm, goto_map->parts[0].start_tile);
322
323 if (return_path == NULL) {
324 log_goto_path(" no return path found");
325
326 if (p->start_tile == ptile) {
327 /* This mean we cannot reach the start point. It is probably,
328 * a path-finding bug, but don't make infinite recursion. */
329
330 if (!goto_warned) {
331 log_error("No path found to reach the start point.");
333 }
334
335 if (old_path != NULL) {
338 }
340 p->path = NULL;
345 }
346 return FALSE;
347 }
348
349 p->path = old_path;
350
351 if (p->path != NULL) {
353
354 p->end_tile = pos->tile;
355 p->end_moves_left = pos->moves_left;
356 p->end_fuel_left = pos->fuel_left;
357 }
358
361
362 return FALSE;
363 }
364
365 log_goto_path(" returned path found:");
366 pf_path_print(return_path, LOG_GOTO_PATH);
367
369 /* We cannot reuse old path because:
370 * 1- the start tile isn't the same.
371 * 2- the turn number neither (impossible to do in backward mode). */
374 }
375 goto_path_redraw(return_path, NULL);
376 goto_map->patrol.return_path = return_path;
377 }
378
381
382 log_goto_path("To (%d,%d) part %d: total_MC: %d",
383 TILE_XY(ptile), goto_map->num_parts,
386 : new_path)->total_MC);
387
388 return TRUE;
389}
390
391/************************************************************************/
396{
397 struct part *p = &goto_map->parts[goto_map->num_parts - 1];
398
399 if (NULL != p->path) {
400 /* Otherwise no need to update */
402 }
403}
404
405/************************************************************************/
408static void fill_parameter_part(struct pf_parameter *param,
409 const struct goto_map *goto_map,
410 const struct part *p)
411{
412 *param = goto_map->template;
413
414 if (p->start_tile == p->end_tile) {
415 /* Copy is enough, we didn't move last part. */
416 fc_assert(p->path->length == 1);
417 return;
418 }
419
420 param->start_tile = p->end_tile;
423 if (can_exist_at_tile(&(wld.map), param->utype, param->start_tile)) {
425 } else {
426 const struct unit *transporter =
428
431 }
432}
433
434/************************************************************************/
439static void add_part(struct goto_map *goto_map)
440{
441 struct part *p;
442 struct pf_parameter parameter;
443 struct unit *punit = goto_map_unit(goto_map);
444
446 goto_map->parts =
448 goto_map->num_parts * sizeof(*goto_map->parts));
449 p = &goto_map->parts[goto_map->num_parts - 1];
450
451 if (goto_map->num_parts == 1) {
452 /* first part */
454 parameter = goto_map->template;
455 } else {
456 struct part *prev = &goto_map->parts[goto_map->num_parts - 2];
457
458 p->start_tile = prev->end_tile;
459 fill_parameter_part(&parameter, goto_map, prev);
460 }
461 p->path = NULL;
462 p->end_tile = p->start_tile;
463 parameter.start_tile = p->start_tile;
464 p->map = pf_map_new(&parameter);
465}
466
467/************************************************************************/
471{
472 struct part *p = &goto_map->parts[goto_map->num_parts - 1];
473
475
477 if (p->path) {
478 /* We do not always have a path */
480 }
483}
484
485/************************************************************************/
489{
490 bool duplicate_of_last = TRUE;
491
493 if (NULL == goto_destination) {
494 /* Not a valid position. */
495 return FALSE;
496 }
497
499 const struct part *last_part = &goto_map->parts[goto_map->num_parts - 1];
500
501 if (last_part->path == NULL) {
502 /* The current part has zero length. */
503 return FALSE;
504 }
505 if (last_part->start_tile != last_part->end_tile) {
507 }
509 if (duplicate_of_last) {
510 return FALSE;
511 }
512
516
518 return TRUE;
519}
520
521/************************************************************************/
526{
527 bool popped = FALSE;
528
531 struct part *p = &goto_map->parts[goto_map->num_parts - 1];
532 struct tile *end_tile = p->end_tile;
533
534 if (goto_map->num_parts == 1) {
535 /* we don't have any waypoint but the start pos. */
536 continue;
537 }
538 popped = TRUE;
539
541
542 /*
543 * Set the end position of the previous part (now the last) to the
544 * end position of the last part (now gone). I.e. redraw a line to
545 * the mouse position.
546 */
547 update_last_part(goto_map, end_tile);
549 return popped;
550}
551
552/************************************************************************/
556static unsigned get_EC(const struct tile *ptile, enum known_type known,
557 const struct pf_parameter *param)
558{
559 return 1;
560}
561
562/************************************************************************/
566static enum tile_behavior get_TB_aggr(const struct tile *ptile,
567 enum known_type known,
568 const struct pf_parameter *param)
569{
570 if (known == TILE_UNKNOWN) {
572 return TB_IGNORE;
573 }
574 } else if (is_non_allied_unit_tile(ptile, param->owner,
576 || is_non_allied_city_tile(ptile, param->owner)) {
577 /* Can attack but can't count on going through */
578 return TB_DONT_LEAVE;
579 }
580
581 return TB_NORMAL;
582}
583
584/************************************************************************/
588static enum tile_behavior get_TB_caravan(const struct tile *ptile,
589 enum known_type known,
590 const struct pf_parameter *param)
591{
592 if (known == TILE_UNKNOWN) {
594 return TB_IGNORE;
595 }
596 } else if (is_non_allied_city_tile(ptile, param->owner)) {
597 /* Units that can establish a trade route, enter a market place or
598 * establish an embassy can travel to, but not through, enemy cities.
599 * FIXME: ACTION_HELP_WONDER units cannot. */
600 return TB_DONT_LEAVE;
601 } else if (is_non_allied_unit_tile(ptile, param->owner,
603 /* Note this must be below the city check. */
604 return TB_IGNORE;
605 }
606
607 /* Includes empty, allied, or allied-city tiles. */
608 return TB_NORMAL;
609}
610
611/************************************************************************/
615static int get_activity_time(const struct tile *ptile,
616 const struct player *pplayer)
617{
618 struct terrain *pterrain = tile_terrain(ptile);
619 int activity_mc = 0;
620
622
623 switch (connect_activity) {
625 if (pterrain->irrigation_time == 0) {
626 return -1;
627 }
628 extra_type_iterate(pextra) {
630 && tile_has_extra(ptile, pextra)) {
631 /* Don't replace old extras. */
632 return -1;
633 }
635
636 if (tile_has_extra(ptile, connect_tgt)) {
637 break;
638 }
639
640 activity_mc = pterrain->irrigation_time;
641 break;
644
645 if (!tile_has_extra(ptile, connect_tgt)) {
646 struct tile *vtile;
647 int single_mc;
648
649 vtile = tile_virtual_new(ptile);
652
653 if (single_mc < 0) {
654 return -1;
655 }
656
658 }
659 break;
660 default:
661 log_error("Invalid connect activity: %d.", connect_activity);
662 }
663
664 return activity_mc;
665}
666
667/************************************************************************/
671static bool is_non_allied_city_adjacent(const struct player *pplayer,
672 const struct tile *ptile)
673{
674 adjc_iterate(&(wld.map), ptile, tile1) {
675 if (is_non_allied_city_tile(tile1, pplayer)) {
676 return TRUE;
677 }
679
680 return FALSE;
681}
682
683/************************************************************************/
692static int get_connect_road(const struct tile *src_tile, enum direction8 dir,
693 const struct tile *dest_tile,
694 int src_cost, int src_extra,
695 unsigned *dest_cost, unsigned *dest_extra,
696 const struct pf_parameter *param)
697{
698 int activity_time, move_cost, moves_left;
699 int total_cost, total_extra;
700 struct road_type *proad;
701
702 if (tile_get_known(dest_tile, param->owner) == TILE_UNKNOWN) {
703 return -1;
704 }
705
706 activity_time = get_activity_time(dest_tile, param->owner);
707 if (activity_time < 0) {
708 return -1;
709 }
710
711 move_cost = param->get_MC(src_tile, PF_MS_NATIVE, dest_tile, PF_MS_NATIVE,
712 param);
714 return -1;
715 }
716
717 if (is_non_allied_city_adjacent(param->owner, dest_tile)) {
718 /* We don't want to build roads to enemies plus get ZoC problems */
719 return -1;
720 }
721
723
725
726 if (proad == NULL) {
727 /* No suitable road type available */
728 return -1;
729 }
730
731 /* Ok, the move is possible. What are the costs? */
732
733 /* Extra cost here is the final length of the road */
735
736 /* Special cases: get_MC function doesn't know that we would have built
737 * a road (railroad) on src tile by that time.
738 * We assume that settler building the road can also travel it. */
739 if (tile_has_road(dest_tile, proad)) {
740 move_cost = proad->move_cost;
741 }
742
743 move_cost = MIN(move_cost, param->move_rate);
744 total_cost = src_cost;
745 moves_left = param->move_rate - (src_cost % param->move_rate);
746 if (moves_left < move_cost) {
747 total_cost += moves_left;
748 } else {
749 total_cost += move_cost;
750 }
751
752 /* Now need to include the activity cost. If we have moves left, they
753 * will count as a full turn towards the activity time */
754 moves_left = param->move_rate - (total_cost % param->move_rate);
755 if (activity_time > 0) {
756 int speed = FC_PTR_TO_INT(param->data);
757
759 + (speed - 1)) / speed;
761 total_cost += moves_left;
762 }
763 total_cost += activity_time * param->move_rate;
764
765 /* Now we determine if we have found a better path. When building
766 * road type with positive move_cost, we care most about the length
767 * of the result. When building road type with move_cost 0, we
768 * care most about construction time. */
769
770 /* *dest_cost == -1 means we haven't reached dest until now */
771
772 if (*dest_cost != -1) {
773 if (proad->move_cost > 0) {
774 if (total_extra > *dest_extra
775 || (total_extra == *dest_extra && total_cost >= *dest_cost)) {
776 /* No, this path is worse than what we already have */
777 return -1;
778 }
779 } else {
780 if (total_cost > *dest_cost
781 || (total_cost == *dest_cost && total_extra >= *dest_extra)) {
782 return -1;
783 }
784 }
785 }
786
787 /* Ok, we found a better path! */
788 *dest_cost = total_cost;
790
791 return (proad->move_cost > 0 ?
792 total_extra * PF_TURN_FACTOR + total_cost :
793 total_cost * PF_TURN_FACTOR + total_extra);
794}
795
796/************************************************************************/
802static int get_connect_irrig(const struct tile *src_tile,
803 enum direction8 dir,
804 const struct tile *dest_tile,
805 int src_cost, int src_extra,
806 unsigned *dest_cost, unsigned *dest_extra,
807 const struct pf_parameter *param)
808{
809 int activity_time, move_cost, moves_left, total_cost;
810
811 if (tile_get_known(dest_tile, param->owner) == TILE_UNKNOWN) {
812 return -1;
813 }
814
815 activity_time = get_activity_time(dest_tile, param->owner);
816 if (activity_time < 0) {
817 return -1;
818 }
819
820 if (!is_cardinal_dir(dir)) {
821 return -1;
822 }
823
824 move_cost = param->get_MC(src_tile, PF_MS_NATIVE, dest_tile, PF_MS_NATIVE,
825 param);
827 return -1;
828 }
829
830 if (is_non_allied_city_adjacent(param->owner, dest_tile)) {
831 /* We don't want to build irrigation for enemies plus get ZoC problems */
832 return -1;
833 }
834
835 /* Ok, the move is possible. What are the costs? */
836
837 move_cost = MIN(move_cost, param->move_rate);
838 total_cost = src_cost;
839 moves_left = param->move_rate - (src_cost % param->move_rate);
840 if (moves_left < move_cost) {
841 total_cost += moves_left;
842 } else {
843 total_cost += move_cost;
844 }
845
846 /* Now need to include the activity cost. If we have moves left, they
847 * will count as a full turn towards the activity time */
848 moves_left = param->move_rate - (total_cost % param->move_rate);
849 if (activity_time > 0) {
850 int speed = FC_PTR_TO_INT(param->data);
851
853 + (speed - 1)) / speed;
855 total_cost += moves_left;
856 }
857 total_cost += activity_time * param->move_rate;
858
859 /* *dest_cost == -1 means we haven't reached dest until now */
860 if (*dest_cost != -1 && total_cost > *dest_cost) {
861 return -1;
862 }
863
864 /* Ok, we found a better path! */
865 *dest_cost = total_cost;
866 *dest_extra = 0;
867
868 return total_cost;
869}
870
871/************************************************************************/
875static enum tile_behavior
876no_fights_or_unknown_goto(const struct tile *ptile,
877 enum known_type known,
878 const struct pf_parameter *p)
879{
881 /* Special case allowing goto into the unknown. */
882 return TB_NORMAL;
883 }
884
885 return no_fights_or_unknown(ptile, known, p);
886}
887
888/************************************************************************/
892static void goto_fill_parameter_base(struct pf_parameter *parameter,
893 const struct unit *punit)
894{
895 pft_fill_unit_parameter(parameter, &(wld.map), punit);
896
897 fc_assert(parameter->get_EC == NULL);
898 fc_assert(parameter->get_TB == NULL);
899 fc_assert(parameter->get_MC != NULL);
900 fc_assert(parameter->start_tile == unit_tile(punit));
901 fc_assert(!parameter->omniscience);
902
903 parameter->get_EC = get_EC;
905 parameter->get_TB = get_TB_aggr;
908 parameter->get_TB = get_TB_caravan;
909 } else {
911 }
912}
913
914/************************************************************************/
926 const struct unit *punit)
927{
928 struct pf_parameter *parameter = &goto_map->template;
929
931
933
934 switch (hover_state) {
935 case HOVER_CONNECT:
936 {
938 int speed;
939
941 parameter->get_costs = get_connect_irrig;
942 } else {
943 parameter->get_costs = get_connect_road;
944 }
945 parameter->get_moves_left_req = NULL;
946
948 parameter->data = FC_INT_TO_PTR(speed);
949
950 /* Take into account the activity time at the origin */
953
954 if (activity_initial > 0) {
955 /* First action is activity */
956 parameter->moves_left_initially = parameter->move_rate;
957 /* Number of turns, rounding up */
960 if (punit->moves_left == 0) {
962 }
963 } else {
965 }
966 }
967 break;
968 case HOVER_GOTO:
969 case HOVER_PATROL:
972 /* TODO: consider doing the same for other actor consuming actions. */
973 /* We only want targets reachable immediately... */
974 parameter->move_rate = 0;
975 /* ...then we don't need to deal with dangers or refuel points. */
976 parameter->is_pos_dangerous = NULL;
977 parameter->get_moves_left_req = NULL;
978 } else {
980 }
981 break;
984 "Path finding during target selection");
985 break;
986 case HOVER_TELEPORT:
987 fc_assert_msg(hover_state != HOVER_TELEPORT, "Goto with HOVER_TELEPORT?");
988 break;
989 case HOVER_NONE:
990 case HOVER_PARADROP:
992 fc_assert_msg(hover_state != HOVER_NONE, "Goto with HOVER_NONE?");
994 "Goto with HOVER_PARADROP?");
996 "Goto with HOVER_ACT_SEL_TGT?");
997 break;
998 };
999}
1000
1001/************************************************************************/
1005void enter_goto_state(struct unit_list *punits)
1006{
1008
1009 /* Can't have selection rectangle and goto going on at the same time. */
1011
1014
1016
1021}
1022
1023/************************************************************************/
1027{
1028 if (!goto_is_active()) {
1029 return;
1030 }
1031
1036
1039}
1040
1041/************************************************************************/
1045{
1046 if (!goto_is_active()) {
1047 return;
1048 }
1049
1051 if (ptest == punit) {
1054 /* Stop now, links are gone! */
1055 break;
1056 }
1058}
1059
1060/************************************************************************/
1064{
1065 return (NULL != goto_maps && 0 != goto_map_list_size(goto_maps));
1066}
1067
1068/************************************************************************/
1072bool goto_get_turns(int *min, int *max)
1073{
1074 fc_assert_ret_val(min != NULL, FALSE);
1075 fc_assert_ret_val(max != NULL, FALSE);
1076
1077 *min = FC_INFINITY;
1078 *max = -1;
1079
1080 if (!goto_is_active()) {
1081 return FALSE;
1082 }
1083 if (NULL == goto_destination) {
1084 /* Not a valid position. */
1085 return FALSE;
1086 }
1087
1088 if (hover_state == HOVER_CONNECT) {
1089 /* In connect mode, we want to know the turn number the activity will
1090 * be finished. */
1092
1094 bool moved = FALSE;
1095 int turns = goto_map->connect.initial_turns;
1096 int i;
1097
1098 for (i = 0; i < goto_map->num_parts; i++) {
1099 const struct pf_path *path = goto_map->parts[i].path;
1100
1102 if (!moved && path->length > 1) {
1103 moved = TRUE;
1104 }
1105 }
1106
1107 if (moved && activity_time > 0) {
1108 turns++;
1109 }
1110
1111 if (turns < *min) {
1112 *min = turns;
1113 }
1114 if (turns > *max) {
1115 *max = turns;
1116 }
1118 } else {
1119 /* In other modes, we want to know the turn number to reach the tile. */
1121 int turns = 0;
1122 int i;
1123
1124 for (i = 0; i < goto_map->num_parts; i++) {
1126 }
1130 }
1131
1132 if (turns < *min) {
1133 *min = turns;
1134 }
1135 if (turns > *max) {
1136 *max = turns;
1137 }
1139 }
1140
1141 return TRUE;
1142}
1143
1144/************************************************************************/
1148bool goto_tile_state(const struct tile *ptile, enum goto_tile_state *state,
1149 int *turns, bool *waypoint)
1150{
1151 fc_assert_ret_val(ptile != NULL, FALSE);
1152 fc_assert_ret_val(turns != NULL, FALSE);
1153 fc_assert_ret_val(waypoint != NULL, FALSE);
1154
1155 if (!goto_is_active()) {
1156 return FALSE;
1157 }
1158
1159 *state = -1;
1160 *turns = -1;
1161 *waypoint = FALSE;
1162
1163 if (hover_state == HOVER_CONNECT) {
1164 /* In connect mode, we want to know the turn number the activity will
1165 * be finished. */
1166 int activity_time;
1167
1168 if (tile_get_known(ptile, client_player()) == TILE_UNKNOWN) {
1169 return FALSE; /* We never connect on unknown tiles. */
1170 }
1171
1173
1175 const struct pf_path *path;
1176 const struct pf_position *pos = NULL; /* Keep compiler happy! */
1178 int turns_for_map = -2;
1179 bool moved = FALSE;
1180 int i, j;
1181
1182 for (i = 0; i < goto_map->num_parts; i++) {
1183 if (i > 0 && goto_map->parts[i].start_tile == ptile) {
1184 *waypoint = TRUE;
1185 }
1186
1187 path = goto_map->parts[i].path;
1188 if (path == NULL || path->length == 0) {
1189 continue;
1190 }
1191
1192 for (j = 0; j < path->length; j++) {
1193 pos = path->positions + j;
1194 if (!moved && j > 0) {
1195 moved = TRUE;
1196 }
1197 if (pos->tile != ptile) {
1198 continue;
1199 }
1200 if (activity_time > 0) {
1201 if (map_turns + pos->turn + moved > turns_for_map) {
1202 turns_for_map = map_turns + pos->turn + moved;
1203 }
1204 } else if (pos->moves_left == 0) {
1205 if (map_turns + pos->turn > turns_for_map) {
1206 turns_for_map = map_turns + pos->turn + moved;
1207 }
1208 }
1209 }
1210 map_turns += pos->turn;
1211 }
1212
1213 if (ptile == goto_destination) {
1214 int ml = (pos != NULL ? pos->moves_left : 0);
1215
1216 if (moved && activity_time > 0) {
1217 map_turns++;
1218 }
1219 if (map_turns > *turns) {
1220 *state = (activity_time > 0 || ml == 0
1222 *turns = map_turns;
1223 } else if (map_turns == *turns
1224 && *state == GTS_MP_LEFT
1225 && (activity_time > 0 || ml == 0)) {
1226 *state = GTS_EXHAUSTED_MP;
1227 }
1228 } else {
1229 if (activity_time > 0) {
1230 if (turns_for_map > *turns) {
1231 *state = GTS_TURN_STEP;
1232 *turns = turns_for_map;
1233 }
1234 } else {
1235 if (turns_for_map + 1 > *turns) {
1236 *state = GTS_TURN_STEP;
1237 *turns = turns_for_map + 1;
1238 }
1239 }
1240 }
1242 } else {
1243 bool mark_on_map = FALSE;
1244
1245 /* In other modes, we want to know the turn number to reach the tile. */
1247 const struct tile *destination;
1248 const struct pf_path *path;
1249 const struct pf_position *pos = NULL; /* Keep compiler happy! */
1250 const struct pf_position *last_pos = NULL;
1251 int map_turns = 0;
1252 int turns_for_map = -2;
1253 int i, j;
1254
1255 for (i = 0; i < goto_map->num_parts; i++) {
1256 if (i > 0 && goto_map->parts[i].start_tile == ptile) {
1257 mark_on_map = *waypoint = TRUE;
1258 }
1259
1260 path = goto_map->parts[i].path;
1261 if (path == NULL || path->length == 0) {
1262 continue;
1263 }
1264 last_pos = path->positions;
1265 for (j = 0; j < path->length; j++) {
1266 pos = path->positions + j;
1267 /* turn to reach was increased in that step */
1268 if (pos->turn != last_pos->turn
1269 && pos->tile == ptile) {
1270 mark_on_map = TRUE;
1271 }
1272 if (pos->moves_left == 0 && last_pos->moves_left != 0
1273 && pos->tile == ptile) {
1274 mark_on_map = TRUE;
1275 }
1276 if (pos->tile == ptile
1277 /* End turn case. */
1278 && (pos->moves_left == 0
1279 /* Waiting case. */
1280 || (j < path->length - 1 && (pos + 1)->tile == ptile))
1281 && map_turns + pos->turn > turns_for_map) {
1282 turns_for_map = map_turns + pos->turn;
1283 }
1284 last_pos = pos;
1285 }
1286 map_turns += pos->turn;
1287 }
1288
1291 && goto_map->patrol.return_path->length > 0) {
1292 path = goto_map->patrol.return_path;
1293
1294 for (j = 0; j < path->length; j++) {
1295 pos = path->positions + j;
1296 if (pos->tile == ptile
1297 /* End turn case. */
1298 && (pos->moves_left == 0
1299 /* Waiting case. */
1300 || (j < path->length - 1 && (pos + 1)->tile == ptile))
1301 && map_turns + pos->turn > turns_for_map) {
1302 turns_for_map = map_turns + pos->turn;
1303 }
1304 }
1305 map_turns += pos->turn;
1306 destination = pos->tile;
1307 } else {
1309 }
1310
1311 if (ptile == destination) {
1312 int ml = (pos != NULL ? pos->moves_left : 0);
1313
1314 if (map_turns > *turns) {
1315 mark_on_map = TRUE;
1316 *state = (ml == 0 ? GTS_EXHAUSTED_MP : GTS_MP_LEFT);
1317 *turns = map_turns;
1318 } else if (map_turns == *turns
1319 && *state == GTS_MP_LEFT
1320 && ml == 0) {
1321 *state = GTS_EXHAUSTED_MP;
1322 }
1323 } else {
1324 if (turns_for_map > *turns) {
1325 *state = GTS_TURN_STEP;
1326 *turns = turns_for_map;
1327 }
1328 }
1330
1331 return mark_on_map;
1332 }
1333
1334 return (*turns != -1 || *waypoint);
1335}
1336
1337/************************************************************************/
1342bool is_valid_goto_draw_line(struct tile *dest_tile)
1343{
1345 if (NULL == dest_tile) {
1346 return FALSE;
1347 }
1348
1349 /* assume valid destination */
1350 goto_destination = dest_tile;
1351
1353 if (!update_last_part(goto_map, dest_tile)) {
1355 }
1357
1358 /* Update goto data in info label. */
1360 return (NULL != goto_destination);
1361}
1362
1363/************************************************************************/
1368{
1369 struct packet_unit_orders p;
1370
1371 if (!can_client_issue_orders()) {
1372 return;
1373 }
1374
1375 /* Clear the orders by sending an empty orders path. */
1376 log_goto_packet("Clearing orders for unit %d.", punit->id);
1377 p.unit_id = punit->id;
1379 p.repeat = p.vigilant = FALSE;
1380 p.length = 0;
1384}
1385
1386/************************************************************************/
1389static void make_path_orders(struct unit *punit, struct pf_path *path,
1390 enum unit_orders orders,
1391 struct unit_order *final_order,
1392 struct unit_order *order_list,
1393 int *length, int *dest_tile)
1394{
1395 int i;
1396 struct tile *old_tile;
1397
1398 fc_assert_ret(path != NULL);
1400 "Unit %d has moved without goto cancelation.",
1401 punit->id);
1402 fc_assert_ret(length != NULL);
1403
1404 /* We skip the start position. */
1405 *length = path->length - 1;
1406 fc_assert(*length < MAX_LEN_ROUTE);
1407 old_tile = path->positions[0].tile;
1408
1409 /* If the path has n positions it takes n-1 steps. */
1410 for (i = 0; i < path->length - 1; i++) {
1411 struct tile *new_tile = path->positions[i + 1].tile;
1412
1413 if (same_pos(new_tile, old_tile)) {
1414 order_list[i].order = ORDER_FULL_MP;
1415 order_list[i].dir = DIR8_ORIGIN;
1416 order_list[i].activity = ACTIVITY_LAST;
1417 order_list[i].target = NO_TARGET;
1418 order_list[i].sub_target = NO_TARGET;
1419 order_list[i].action = ACTION_NONE;
1420 log_goto_packet(" packet[%d] = wait: %d,%d", i, TILE_XY(old_tile));
1421 } else {
1422 order_list[i].order = orders;
1424 order_list[i].activity = ACTIVITY_LAST;
1425 order_list[i].target = NO_TARGET;
1426 order_list[i].sub_target = NO_TARGET;
1427 order_list[i].action = ACTION_NONE;
1428 log_goto_packet(" packet[%d] = move %s: %d,%d => %d,%d",
1429 i, dir_get_name(order_list[i].dir),
1431 }
1433 }
1434
1435 if (i > 0
1436 && order_list[i - 1].order == ORDER_MOVE) {
1437 struct player *cplayer = client_player();
1438
1442 /* Won't be able to perform a regular move to the target tile... */
1443 if (!final_order) {
1444 /* ...and no final order exists. Choose what to do when the unit gets
1445 * there. */
1446 order_list[i - 1].order = ORDER_ACTION_MOVE;
1447 } else {
1448 /* ...and a final order exist. Can't assume an action move. Did the
1449 * caller hope that the situation would change before the unit got
1450 * there? */
1451
1452 /* It's currently illegal to walk into tiles with non-allied units or
1453 * cities. Some actions causes the actor to enter the target tile but
1454 * that is a part of the action it self, not a regular pre action
1455 * move. */
1456 log_verbose("unit or city blocks the path of your %s",
1458 }
1459 }
1460 }
1461
1462 if (final_order) {
1463 /* Append the final order after moving to the target tile. */
1464 order_list[i].order = final_order->order;
1465 order_list[i].dir = final_order->dir;
1466 order_list[i].activity = (final_order->order == ORDER_ACTIVITY)
1467 ? final_order->activity : ACTIVITY_LAST;
1468 order_list[i].target = final_order->target;
1469 order_list[i].sub_target = final_order->sub_target;
1470 order_list[i].action = final_order->action;
1471 (*length)++;
1472 }
1473
1474 if (dest_tile) {
1475 *dest_tile = tile_index(old_tile);
1476 }
1477}
1478
1479/************************************************************************/
1482static void send_path_orders(struct unit *punit, struct pf_path *path,
1483 bool repeat, bool vigilant,
1484 enum unit_orders orders,
1485 struct unit_order *final_order)
1486{
1487 struct packet_unit_orders p;
1488
1489 if (path->length == 1 && final_order == NULL) {
1490 return; /* No path at all, no need to spam the server. */
1491 }
1492
1493 memset(&p, 0, sizeof(p));
1494 p.unit_id = punit->id;
1496 p.repeat = repeat;
1497 p.vigilant = vigilant;
1498
1499 log_goto_packet("Orders for unit %d:", punit->id);
1500 log_goto_packet(" Repeat: %d. Vigilant: %d.",
1501 p.repeat, p.vigilant);
1502
1504 p.orders, &p.length, &p.dest_tile);
1505
1508}
1509
1510/************************************************************************/
1513static void send_rally_path_orders(struct city *pcity, struct unit *punit,
1514 struct pf_path *path, bool vigilant,
1515 bool persistent,
1516 enum unit_orders orders,
1517 struct unit_order *final_order)
1518{
1519 struct packet_city_rally_point p;
1520
1521 memset(&p, 0, sizeof(p));
1522 p.id = pcity->id;
1523 p.vigilant = vigilant;
1525
1526 log_goto_packet("Rally orders for city %d:", pcity->id);
1527 log_goto_packet(" Vigilant: %d.", p.vigilant);
1528
1530 p.orders, &p.length, NULL);
1531
1533}
1534
1535/************************************************************************/
1538void send_goto_path(struct unit *punit, struct pf_path *path,
1539 struct unit_order *final_order)
1540{
1542}
1543
1544/************************************************************************/
1547static void send_rally_path(struct city *pcity, struct unit *punit,
1548 bool persistent, struct pf_path *path,
1549 struct unit_order *final_order)
1550{
1553}
1554
1555/************************************************************************/
1559bool send_goto_tile(struct unit *punit, struct tile *ptile)
1560{
1561 struct pf_parameter parameter;
1562 struct pf_map *pfm;
1563 struct pf_path *path;
1564
1565 goto_fill_parameter_base(&parameter, punit);
1566 pfm = pf_map_new(&parameter);
1567 path = pf_map_path(pfm, ptile);
1569
1570 if (path) {
1571 send_goto_path(punit, path, NULL);
1572 pf_path_destroy(path);
1573 return TRUE;
1574 } else {
1575 return FALSE;
1576 }
1577}
1578
1579/************************************************************************/
1583bool send_rally_tile(struct city *pcity, struct tile *ptile, bool persistent)
1584{
1585 const struct unit_type *putype;
1586 struct unit *punit;
1587 struct pf_parameter parameter;
1588 struct pf_map *pfm;
1589 struct pf_path *path;
1590
1591 fc_assert_ret_val(pcity != NULL, FALSE);
1592 fc_assert_ret_val(ptile != NULL, FALSE);
1593
1594 /* Create a virtual unit of the type being produced by the city. */
1595 if (pcity->production.kind != VUT_UTYPE) {
1596 /* Can only give orders to units. */
1597 return FALSE;
1598 }
1599
1600 putype = pcity->production.value.utype;
1603 putype));
1604
1605 /* Use the unit to find a path to the destination tile. */
1606 goto_fill_parameter_base(&parameter, punit);
1607 pfm = pf_map_new(&parameter);
1608 path = pf_map_path(pfm, ptile);
1610
1611 if (path) {
1612 /* Send orders to server. */
1613 send_rally_path(pcity, punit, persistent, path, NULL);
1615 pf_path_destroy(path);
1616
1617 return TRUE;
1618 } else {
1620
1621 return FALSE;
1622 }
1623}
1624
1625/************************************************************************/
1629bool send_attack_tile(struct unit *punit, struct tile *ptile)
1630{
1631 struct pf_parameter parameter;
1632 struct pf_map *pfm;
1633 struct pf_path *path;
1634
1635 goto_fill_parameter_base(&parameter, punit);
1636 parameter.move_rate = 0;
1637 parameter.is_pos_dangerous = NULL;
1638 parameter.get_moves_left_req = NULL;
1639 pfm = pf_map_new(&parameter);
1640 path = pf_map_path(pfm, ptile);
1642
1643 if (path) {
1644 send_path_orders(punit, path, false, false, ORDER_ACTION_MOVE, NULL);
1645 pf_path_destroy(path);
1646 return TRUE;
1647 }
1648 return FALSE;
1649}
1650
1651/************************************************************************/
1656{
1659 int i;
1660 struct pf_path *path = NULL;
1661 struct part *last_part = &goto_map->parts[goto_map->num_parts - 1];
1662
1663 if (NULL == last_part->path) {
1664 /* Cannot move there */
1665 continue;
1666 }
1667
1668 for (i = 0; i < goto_map->num_parts; i++) {
1670 }
1672
1674
1677}
1678
1679/************************************************************************/
1682static bool order_recursive_roads(struct tile *ptile, struct extra_type *pextra,
1683 struct packet_unit_orders *p, int rec)
1684{
1685 if (rec > MAX_EXTRA_TYPES) {
1686 return FALSE;
1687 }
1688
1689 if (!is_extra_caused_by(pextra, EC_ROAD)) {
1690 return FALSE;
1691 }
1692
1693 if (tile_has_extra(ptile, pextra)) {
1694 /* No need to build what is already there. */
1695 return TRUE;
1696 }
1697
1698 extra_deps_iterate(&(pextra->reqs), pdep) {
1699 if (!tile_has_extra(ptile, pdep)) {
1700 if (!order_recursive_roads(ptile, pdep, p, rec + 1)) {
1701 return FALSE;
1702 }
1703 }
1705
1707 p->orders[p->length].dir = DIR8_ORIGIN;
1709 p->orders[p->length].target = ptile->index;
1710 p->orders[p->length].sub_target = extra_index(pextra);
1712 p->length++;
1713
1714 return TRUE;
1715}
1716
1717/************************************************************************/
1722 struct extra_type *tgt)
1723{
1726 int i;
1727 struct packet_unit_orders p;
1728 struct tile *old_tile;
1729 struct pf_path *path = NULL;
1730 struct part *last_part = &goto_map->parts[goto_map->num_parts - 1];
1731
1732 if (NULL == last_part->path) {
1733 /* Cannot move there */
1734 continue;
1735 }
1736
1737 memset(&p, 0, sizeof(p));
1738
1739 i = 0;
1740 do {
1742 i++;
1743 } while (i < goto_map->num_parts);
1744
1745 p.unit_id = punit->id;
1747 p.repeat = FALSE;
1748 p.vigilant = FALSE; /* Should be TRUE? */
1749
1750 p.length = 0;
1752
1753 for (i = 0; i < path->length; i++) {
1754 switch (activity) {
1755 case ACTIVITY_IRRIGATE:
1756 if (!tile_has_extra(old_tile, tgt)) {
1757 /* Assume the unit can irrigate or we wouldn't be here. */
1761 p.orders[p.length].target = old_tile->index;
1762 p.orders[p.length].sub_target = extra_index(tgt);
1764 p.length++;
1765 }
1766 break;
1767 case ACTIVITY_GEN_ROAD:
1768 order_recursive_roads(old_tile, tgt, &p, 0);
1769 break;
1770 default:
1771 log_error("Invalid connect activity: %d.", activity);
1772 break;
1773 }
1774
1775 if (i != path->length - 1) {
1776 struct tile *new_tile = path->positions[i + 1].tile;
1777
1779
1787 p.length++;
1788
1790 }
1791 }
1792
1794
1798}
1799
1800/************************************************************************/
1807static bool order_wants_direction(enum unit_orders order, action_id act_id,
1808 struct tile *tgt_tile, struct unit *punit)
1809{
1810 struct player *cplayer;
1811
1812 switch (order) {
1813 case ORDER_MOVE:
1814 case ORDER_ACTION_MOVE:
1815 /* Not only is it legal. It is mandatory. A move is always done in a
1816 * direction. */
1817 return TRUE;
1819 if (!action_id_distance_accepted(act_id, 0)) {
1820 /* Always illegal to do to a target on the actor's own tile. */
1821 return TRUE;
1822 }
1823
1824 if (!action_id_distance_accepted(act_id, 1)) {
1825 /* Always illegal to perform to a target on a neighbor tile. */
1826 return FALSE;
1827 }
1828
1833 /* Won't be able to move to the target tile to perform the action on
1834 * top of it. */
1835 /* TODO: Detect situations where it also would be illegal to perform
1836 * the action from the neighbor tile. */
1837 return TRUE;
1838 }
1839
1841 /* Prefer efficiency over safety among allies. */
1843 return TRUE;
1844 }
1845
1846 return FALSE;
1847 default:
1848 return FALSE;
1849 }
1850}
1851
1852/************************************************************************/
1856static bool order_demands_direction(enum unit_orders order, action_id act_id)
1857{
1858 switch (order) {
1859 case ORDER_MOVE:
1860 case ORDER_ACTION_MOVE:
1861 /* A move is always done in a direction. */
1862 return TRUE;
1864 if (!action_id_distance_accepted(act_id, 0)) {
1865 /* Always illegal to do to a target on the actor's own tile. */
1866 return TRUE;
1867 }
1868
1869 return FALSE;
1870 default:
1871 return FALSE;
1872 }
1873}
1874
1875/************************************************************************/
1882{
1885 int i;
1886 struct tile *tgt_tile;
1887 struct pf_path *path = NULL;
1888 struct part *last_part = &goto_map->parts[goto_map->num_parts - 1];
1889
1890 if (NULL == last_part->path) {
1891 /* Cannot move there */
1892 continue;
1893 }
1894
1895 i = 0;
1896 do {
1898 i++;
1899 } while (i < goto_map->num_parts);
1900
1902
1904
1905 /* Make the last move in a plain goto try to pop up the action
1906 * selection dialog rather than moving to the last tile if it contains
1907 * a domestic, allied or team mate city, unit or unit stack. This can,
1908 * in cases where the action requires movement left, save a turn. */
1914 ACTION_ANY,
1916 FALSE)
1918 ACTION_ANY,
1920 TRUE)
1922 ACTION_ANY,
1923 DS_TEAM,
1924 TRUE)))) {
1925 /* Try to pop up the action selection dialog before moving to the
1926 * target tile. */
1928 }
1929
1930 /* Handle single-step goto like single-step move. */
1931 if (goto_last_order == ORDER_LAST && path->length == 2
1934 }
1935
1936 if (goto_last_order == ORDER_LAST) {
1938 } else if (path->length > 1
1941 struct unit_order order;
1942 int last_order_dir;
1943 struct tile *on_tile;
1945
1946 if (path->length > 1 && goto_last_tgt == NO_TARGET
1947 && ((on_tile = path->positions[path->length - 2].tile))
1949 tgt_tile, punit)
1950 && !same_pos(on_tile, tgt_tile)) {
1951 /* The last order prefers to handle the last direction it self.
1952 * There exists a tile before the target tile to do it from. */
1953
1954 /* Give the last path direction to the final order. */
1956
1957 /* The last path direction is now spent. */
1959 } else {
1963
1964 /* Target the tile the actor is standing on or goto_last_tgt. */
1966 }
1967
1970 ? tgt_tile->index : goto_last_tgt);
1972 }
1973
1974 order.order = goto_last_order;
1975 order.dir = last_order_dir;
1976 order.activity = ACTIVITY_LAST;
1977 order.target = last_order_target;
1979 order.action = goto_last_action;
1980
1981 /* ORDER_ACTIVITY would require real activity */
1983
1984 send_goto_path(punit, path, &order);
1985 }
1986 pf_path_destroy(path);
1988}
1989
1990/************************************************************************/
1995{
1996 struct pf_parameter parameter;
1997 struct pf_map *pfm;
1998 struct pf_path *path = NULL;
1999
2001 /* We're already on a city - don't go anywhere. */
2002 return NULL;
2003 }
2004
2005 goto_fill_parameter_base(&parameter, punit);
2006 pfm = pf_map_new(&parameter);
2007
2008 pf_map_tiles_iterate(pfm, ptile, FALSE) {
2009 if (is_allied_city_tile(ptile, unit_owner(punit))) {
2010 path = pf_map_path(pfm, ptile);
2011 break;
2012 }
2014
2016
2017 return path;
2018}
2019
2020/************************************************************************/
2023struct tile *tile_before_end_path(struct unit *punit, struct tile *ptile)
2024{
2025 struct pf_parameter parameter;
2026 struct pf_map *pfm;
2027 struct tile *dtile;
2028 struct pf_path *path;
2029
2030 goto_fill_parameter_base(&parameter, punit);
2031 parameter.move_rate = 0;
2032 parameter.is_pos_dangerous = NULL;
2033 parameter.get_moves_left_req = NULL;
2034 pfm = pf_map_new(&parameter);
2035 path = pf_map_path(pfm, ptile);
2036 if (path == NULL) {
2037 return NULL;
2038 }
2039 if (path->length < 2) {
2040 dtile = NULL;
2041 } else {
2042 dtile = path->positions[path->length - 2].tile;
2043 }
2045
2046 return dtile;
2047}
bool action_id_exists(const action_id act_id)
Definition actions.c:1043
#define action_id_distance_accepted(act_id, distance)
Definition actions.h:439
#define ACTION_ANY
Definition actions.h:52
#define action_id_has_result_safe(act_id, result)
Definition actions.h:420
#define ACTION_NONE
Definition actions.h:55
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
int city_production_unit_veteran_level(struct city *pcity, const struct unit_type *punittype)
Definition city.c:804
static bool is_non_allied_city_tile(const struct tile *ptile, const struct player *pplayer)
Definition city.h:763
static bool is_allied_city_tile(const struct tile *ptile, const struct player *pplayer)
Definition city.h:739
struct civclient client
bool can_client_issue_orders(void)
#define client_player()
char * incite_cost
Definition comments.c:74
#define MAX_LEN_ROUTE
Definition conn_types.h:38
bool unit_is_in_focus(const struct unit *punit)
Definition control.c:383
enum unit_orders goto_last_order
Definition control.c:96
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
int goto_last_tgt
Definition control.c:94
struct extra_type * connect_tgt
Definition control.c:91
struct unit_list * get_units_in_focus(void)
Definition control.c:177
void request_unit_ssa_set(const struct unit *punit, enum server_side_agent agent)
Definition control.c:2101
enum unit_activity connect_activity
Definition control.c:90
enum cursor_hover_state hover_state
Definition control.c:89
void clear_unit_orders(struct unit *punit)
Definition control.c:476
int goto_last_sub_tgt
Definition control.c:95
action_id goto_last_action
Definition control.c:93
@ HOVER_GOTO
Definition control.h:27
@ HOVER_PARADROP
Definition control.h:29
@ HOVER_TELEPORT
Definition control.h:28
@ HOVER_ACT_SEL_TGT
Definition control.h:32
@ HOVER_NONE
Definition control.h:26
@ HOVER_CONNECT
Definition control.h:30
@ HOVER_PATROL
Definition control.h:31
@ HOVER_GOTO_SEL_TGT
Definition control.h:33
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
#define extra_type_iterate(_p)
Definition extras.h:315
#define extra_deps_iterate(_reqs, _dep)
Definition extras.h:371
#define extra_type_iterate_end
Definition extras.h:321
#define is_extra_caused_by(e, c)
Definition extras.h:203
#define extra_index(_e_)
Definition extras.h:183
#define extra_deps_iterate_end
Definition extras.h:379
#define extra_road_get(_e_)
Definition extras.h:191
#define NO_TARGET
Definition fc_types.h:358
#define DIR8_ORIGIN
Definition fc_types.h:459
int action_id
Definition fc_types.h:393
#define MAX_EXTRA_TYPES
Definition fc_types.h:50
struct world wld
Definition game.c:62
static bool goto_warned
Definition goto.c:92
static bool is_non_allied_city_adjacent(const struct player *pplayer, const struct tile *ptile)
Definition goto.c:671
static int get_connect_irrig(const struct tile *src_tile, enum direction8 dir, const struct tile *dest_tile, int src_cost, int src_extra, unsigned *dest_cost, unsigned *dest_extra, const struct pf_parameter *param)
Definition goto.c:802
static void fill_parameter_part(struct pf_parameter *param, const struct goto_map *goto_map, const struct part *p)
Definition goto.c:408
#define LOG_GOTO_PATH
Definition goto.c:43
#define goto_map_list_iterate_end
Definition goto.c:80
static int get_connect_road(const struct tile *src_tile, enum direction8 dir, const struct tile *dest_tile, int src_cost, int src_extra, unsigned *dest_cost, unsigned *dest_extra, const struct pf_parameter *param)
Definition goto.c:692
static void make_path_orders(struct unit *punit, struct pf_path *path, enum unit_orders orders, struct unit_order *final_order, struct unit_order *order_list, int *length, int *dest_tile)
Definition goto.c:1389
static void goto_path_undraw(const struct pf_path *path)
Definition goto.c:237
static enum tile_behavior no_fights_or_unknown_goto(const struct tile *ptile, enum known_type known, const struct pf_parameter *p)
Definition goto.c:876
static bool order_recursive_roads(struct tile *ptile, struct extra_type *pextra, struct packet_unit_orders *p, int rec)
Definition goto.c:1682
static void goto_fill_parameter_full(struct goto_map *goto_map, const struct unit *punit)
Definition goto.c:925
static struct tile * goto_destination
Definition goto.c:103
static unsigned get_EC(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
Definition goto.c:556
static enum tile_behavior get_TB_caravan(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
Definition goto.c:588
void exit_goto_state(void)
Definition goto.c:1026
struct tile * tile_before_end_path(struct unit *punit, struct tile *ptile)
Definition goto.c:2023
bool goto_is_active(void)
Definition goto.c:1063
bool send_attack_tile(struct unit *punit, struct tile *ptile)
Definition goto.c:1629
struct pf_path * path_to_nearest_allied_city(struct unit *punit)
Definition goto.c:1994
static struct goto_map_list * goto_maps
Definition goto.c:91
static void goto_fill_parameter_base(struct pf_parameter *parameter, const struct unit *punit)
Definition goto.c:892
void init_client_goto(void)
Definition goto.c:153
#define goto_map_unit_iterate_end
Definition goto.c:88
void send_patrol_route(void)
Definition goto.c:1655
bool send_rally_tile(struct city *pcity, struct tile *ptile, bool persistent)
Definition goto.c:1583
static void remove_last_part(struct goto_map *goto_map)
Definition goto.c:470
static void send_rally_path_orders(struct city *pcity, struct unit *punit, struct pf_path *path, bool vigilant, bool persistent, enum unit_orders orders, struct unit_order *final_order)
Definition goto.c:1513
bool is_valid_goto_draw_line(struct tile *dest_tile)
Definition goto.c:1342
static void send_path_orders(struct unit *punit, struct pf_path *path, bool repeat, bool vigilant, enum unit_orders orders, struct unit_order *final_order)
Definition goto.c:1482
static bool order_wants_direction(enum unit_orders order, action_id act_id, struct tile *tgt_tile, struct unit *punit)
Definition goto.c:1807
static struct goto_map * goto_map_new(struct unit *punit)
Definition goto.c:108
static bool update_last_part(struct goto_map *goto_map, struct tile *ptile)
Definition goto.c:259
static enum tile_behavior get_TB_aggr(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
Definition goto.c:566
#define goto_map_list_iterate(gotolist, pgoto)
Definition goto.c:78
static void reset_last_part(struct goto_map *goto_map)
Definition goto.c:395
#define log_goto_path
Definition goto.c:44
#define goto_map_unit_iterate(gotolist, pgoto, punit)
Definition goto.c:84
bool goto_add_waypoint(void)
Definition goto.c:488
bool send_goto_tile(struct unit *punit, struct tile *ptile)
Definition goto.c:1559
static struct unit * goto_map_unit(const struct goto_map *goto_map)
Definition goto.c:139
bool goto_pop_waypoint(void)
Definition goto.c:525
#define log_goto_packet
Definition goto.c:45
void send_connect_route(enum unit_activity activity, struct extra_type *tgt)
Definition goto.c:1721
void goto_unit_killed(struct unit *punit)
Definition goto.c:1044
void free_client_goto(void)
Definition goto.c:163
void enter_goto_state(struct unit_list *punits)
Definition goto.c:1005
void send_goto_route(void)
Definition goto.c:1881
bool is_valid_goto_destination(const struct tile *ptile)
Definition goto.c:180
static void goto_path_redraw(const struct pf_path *new_path, const struct pf_path *old_path)
Definition goto.c:188
bool goto_get_turns(int *min, int *max)
Definition goto.c:1072
static int get_activity_time(const struct tile *ptile, const struct player *pplayer)
Definition goto.c:615
static void goto_map_free(struct goto_map *goto_map)
Definition goto.c:122
void request_orders_cleared(struct unit *punit)
Definition goto.c:1367
static void send_rally_path(struct city *pcity, struct unit *punit, bool persistent, struct pf_path *path, struct unit_order *final_order)
Definition goto.c:1547
static bool order_demands_direction(enum unit_orders order, action_id act_id)
Definition goto.c:1856
void send_goto_path(struct unit *punit, struct pf_path *path, struct unit_order *final_order)
Definition goto.c:1538
static void add_part(struct goto_map *goto_map)
Definition goto.c:439
goto_tile_state
Definition goto.h:25
@ GTS_EXHAUSTED_MP
Definition goto.h:28
@ GTS_MP_LEFT
Definition goto.h:27
@ GTS_TURN_STEP
Definition goto.h:26
static struct tile * pos
Definition finddlg.c:53
void update_unit_info_label(struct unit_list *punits)
Definition mapview.c:275
static GtkWidget * persistent
#define fc_assert_msg(condition, message,...)
Definition log.h:181
#define fc_assert_ret(condition)
Definition log.h:191
#define log_verbose(message,...)
Definition log.h:109
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_ret_msg(condition, message,...)
Definition log.h:205
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define log_debug(message,...)
Definition log.h:115
#define log_error(message,...)
Definition log.h:103
int get_direction_for_step(const struct civ_map *nmap, const struct tile *start_tile, const struct tile *end_tile)
Definition map.c:1362
const char * dir_get_name(enum direction8 dir)
Definition map.c:1161
bool is_cardinal_dir(enum direction8 dir)
Definition map.c:1331
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Definition map.c:950
bool is_valid_dir(enum direction8 dir)
Definition map.c:1275
#define adjc_iterate_end
Definition map.h:419
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:414
void cancel_selection_rectangle(void)
void mapdeco_add_gotoline(const struct tile *ptile, enum direction8 dir)
void refresh_tile_mapcanvas(struct tile *ptile, bool full_refresh, bool write_to_screen)
void mapdeco_remove_gotoline(const struct tile *ptile, enum direction8 dir)
#define fc_realloc(ptr, sz)
Definition mem.h:36
#define fc_malloc(sz)
Definition mem.h:34
bool can_exist_at_tile(const struct civ_map *nmap, const struct unit_type *utype, const struct tile *ptile)
Definition movement.c:289
struct client_options gui_options
Definition options.c:71
int send_packet_city_rally_point(struct connection *pc, const struct packet_city_rally_point *packet, bool force_to_send)
int send_packet_unit_orders(struct connection *pc, const struct packet_unit_orders *packet)
struct pf_path * pf_path_concat(struct pf_path *dest_path, const struct pf_path *src_path)
const struct pf_position * pf_path_last_position(const struct pf_path *path)
void pf_path_destroy(struct pf_path *path)
bool pf_path_backtrack(struct pf_path *path, struct tile *ptile)
struct pf_map * pf_map_new(const struct pf_parameter *parameter)
struct pf_path * pf_map_path(struct pf_map *pfm, struct tile *ptile)
void pf_map_destroy(struct pf_map *pfm)
#define pf_path_print(path, level)
#define PF_IMPOSSIBLE_MC
@ PF_MS_NATIVE
#define PF_TURN_FACTOR
#define pf_map_tiles_iterate(ARG_pfm, NAME_tile, COND_from_start)
tile_behavior
@ TB_NORMAL
@ TB_DONT_LEAVE
@ TB_IGNORE
#define pf_map_tiles_iterate_end
void pft_fill_unit_parameter(struct pf_parameter *parameter, const struct civ_map *nmap, const struct unit *punit)
Definition pf_tools.c:843
enum tile_behavior no_fights_or_unknown(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
Definition pf_tools.c:493
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1229
#define MIN(x, y)
Definition shared.h:55
#define FC_INFINITY
Definition shared.h:36
#define FC_PTR_TO_INT(p)
Definition shared.h:95
#define FC_INT_TO_PTR(i)
Definition shared.h:94
Definition city.h:320
int id
Definition city.h:326
struct universal production
Definition city.h:396
struct connection conn
Definition client_main.h:96
bool goto_into_unknown
Definition options.h:161
bool popup_last_move_to_allied
Definition options.h:171
bv_extras conflicts
Definition extras.h:133
struct requirement_vector reqs
Definition extras.h:106
struct goto_map::@134::@137 patrol
int num_parts
Definition goto.c:62
struct pf_path * return_path
Definition goto.c:68
struct unit * focus
Definition goto.c:60
struct goto_map::@134::@136 connect
struct part * parts
Definition goto.c:61
struct pf_parameter template
Definition goto.c:71
int initial_turns
Definition goto.c:65
struct unit_order orders[MAX_LEN_ROUTE]
struct unit_order orders[MAX_LEN_ROUTE]
Definition goto.c:52
int end_moves_left
Definition goto.c:54
struct pf_map * map
Definition goto.c:56
struct tile * start_tile
Definition goto.c:53
struct pf_path * path
Definition goto.c:55
int end_fuel_left
Definition goto.c:54
struct tile * end_tile
Definition goto.c:53
int fuel_left_initially
const struct unit_type * transported_by_initially
enum tile_behavior(* get_TB)(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
const struct player * owner
bool(* is_pos_dangerous)(const struct tile *ptile, enum known_type, const struct pf_parameter *param)
int(* get_moves_left_req)(const struct tile *ptile, enum known_type, const struct pf_parameter *param)
int moves_left_initially
unsigned(* get_MC)(const struct tile *from_tile, enum pf_move_scope src_move_scope, const struct tile *to_tile, enum pf_move_scope dst_move_scope, const struct pf_parameter *param)
int(* get_costs)(const struct tile *from_tile, enum direction8 dir, const struct tile *to_tile, int from_cost, int from_extra, unsigned *to_cost, unsigned *to_extra, const struct pf_parameter *param)
unsigned(* get_EC)(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
const struct unit_type * utype
struct tile * start_tile
unsigned length
struct pf_position * positions
unsigned total_MC
struct tile * tile
int move_cost
Definition road.h:74
int irrigation_time
Definition terrain.h:115
Definition tile.h:50
int index
Definition tile.h:51
enum unit_activity activity
Definition unit.h:95
enum unit_orders order
Definition unit.h:94
int action
Definition unit.h:102
enum direction8 dir
Definition unit.h:104
int target
Definition unit.h:98
int sub_target
Definition unit.h:99
Definition unit.h:140
int moves_left
Definition unit.h:152
int id
Definition unit.h:147
struct unit * transporter
Definition unit.h:186
enum universals_n kind
Definition fc_types.h:880
universals_u value
Definition fc_types.h:879
struct civ_map map
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
void tile_virtual_destroy(struct tile *vtile)
Definition tile.c:1035
bool tile_has_road(const struct tile *ptile, const struct road_type *proad)
Definition tile.c:844
struct tile * tile_virtual_new(const struct tile *ptile)
Definition tile.c:981
enum known_type tile_get_known(const struct tile *ptile, const struct player *pplayer)
Definition tile.c:392
#define tile_index(_pt_)
Definition tile.h:89
known_type
Definition tile.h:35
@ TILE_UNKNOWN
Definition tile.h:36
#define ACTIVITY_FACTOR
Definition tile.h:166
#define tile_terrain(_tile)
Definition tile.h:111
#define TILE_XY(ptile)
Definition tile.h:43
#define tile_has_extra(ptile, pextra)
Definition tile.h:148
const struct unit_type * utype
Definition fc_types.h:698
struct unit * transporter_for_unit_at(const struct unit *pcargo, const struct tile *ptile)
Definition unit.c:1960
int get_activity_rate(const struct unit *punit)
Definition unit.c:522
struct unit * unit_virtual_create(struct player *pplayer, struct city *pcity, const struct unit_type *punittype, int veteran_level)
Definition unit.c:1662
void unit_virtual_destroy(struct unit *punit)
Definition unit.c:1767
#define unit_tile(_pu)
Definition unit.h:397
unit_orders
Definition unit.h:38
@ ORDER_ACTION_MOVE
Definition unit.h:46
@ ORDER_ACTIVITY
Definition unit.h:42
@ ORDER_FULL_MP
Definition unit.h:44
@ ORDER_MOVE
Definition unit.h:40
@ ORDER_LAST
Definition unit.h:50
@ ORDER_PERFORM_ACTION
Definition unit.h:48
static bool is_allied_unit_tile(const struct tile *ptile, const struct player *pplayer)
Definition unit.h:408
#define unit_owner(_pu)
Definition unit.h:396
static bool is_non_allied_unit_tile(const struct tile *ptile, const struct player *pplayer, bool everyone_non_allied)
Definition unit.h:433
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_end
Definition unitlist.h:33
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1587
bool utype_may_act_at_all(const struct unit_type *putype)
Definition unittype.c:359
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:190
bool utype_acts_hostile(const struct unit_type *putype)
Definition unittype.c:443
bool can_utype_do_act_if_tgt_diplrel(const struct unit_type *punit_type, const action_id act_id, const int prop, const bool is_there)
Definition unittype.c:1017
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:624