Freeciv-3.2
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 return punit;
147}
148
149/************************************************************************/
153{
155
157}
158
159/************************************************************************/
175
176/************************************************************************/
179bool is_valid_goto_destination(const struct tile *ptile)
180{
181 return (NULL != goto_destination && ptile == goto_destination);
182}
183
184/************************************************************************/
187static void goto_path_redraw(const struct pf_path *new_path,
188 const struct pf_path *old_path)
189{
190 int start_index = 0;
191 int i;
192
194
195 if (old_path != NULL) {
196 /* We had a path drawn already. Determine how much of it we can reuse
197 * in drawing the new path. */
198 for (i = 0; i < new_path->length - 1 && i < old_path->length - 1; i++) {
199 struct pf_position *old_pos = old_path->positions + i;
200 struct pf_position *new_pos = new_path->positions + i;
201
202 if (old_pos->dir_to_next_pos != new_pos->dir_to_next_pos
203 || old_pos->tile != new_pos->tile) {
204 break;
205 }
206 }
207 start_index = i;
208
209 /* Erase everything we cannot reuse. */
210 for (; i < old_path->length - 1; i++) {
211 struct pf_position *pos = old_path->positions + i;
212
213 if (is_valid_dir(pos->dir_to_next_pos)) {
214 mapdeco_remove_gotoline(pos->tile, pos->dir_to_next_pos);
215 } else {
216 fc_assert(pos->tile == (pos + 1)->tile);
217 }
218 }
219 }
220
221 /* Draw the new path. */
222 for (i = start_index; i < new_path->length - 1; i++) {
223 struct pf_position *pos = new_path->positions + i;
224
225 if (is_valid_dir(pos->dir_to_next_pos)) {
226 mapdeco_add_gotoline(pos->tile, pos->dir_to_next_pos);
227 } else {
228 fc_assert(pos->tile == (pos + 1)->tile);
229 }
230 }
231}
232
233/************************************************************************/
236static void goto_path_undraw(const struct pf_path *path)
237{
238 int i;
239
240 fc_assert_ret(path != NULL);
241
242 for (i = 0; i < path->length - 1; i++) {
243 struct pf_position *pos = path->positions + i;
244
245 if (is_valid_dir(pos->dir_to_next_pos)) {
246 mapdeco_remove_gotoline(pos->tile, pos->dir_to_next_pos);
247 } else {
248 fc_assert(pos->tile == (pos + 1)->tile);
249 }
250 }
251}
252
253/************************************************************************/
259 struct tile *ptile)
260{
261 struct pf_path *old_path, *new_path;
262 struct part *p = &goto_map->parts[goto_map->num_parts - 1];
263
264 old_path = p->path;
265 if (old_path != NULL && pf_path_last_position(old_path)->tile == ptile) {
266 /* Nothing to update. */
267 return TRUE;
268 }
269
270 log_debug("update_last_part(%d,%d) old (%d,%d)-(%d,%d)",
271 TILE_XY(ptile), TILE_XY(p->start_tile), TILE_XY(p->end_tile));
272 new_path = pf_map_path(p->map, ptile);
273
274 if (!new_path) {
275 log_goto_path(" no path found");
276
277 if (p->start_tile == ptile) {
278 /* This mean we cannot reach the start point. It is probably,
279 * a path-finding bug, but don't make infinite recursion. */
280
281 if (!goto_warned) {
282 log_error("No path found to reach the start point.");
284 }
285
286 if (old_path != NULL) {
289 p->path = NULL;
290 }
296 }
297 return FALSE;
298 }
299
301 return FALSE;
302 }
303
304 log_goto_path(" path found:");
306
307 p->path = new_path;
308 p->end_tile = ptile;
311
312 if (hover_state == HOVER_PATROL) {
313 struct pf_parameter parameter;
314 struct pf_map *pfm;
315 struct pf_path *return_path;
316
317 fill_parameter_part(&parameter, goto_map, p);
318 pfm = pf_map_new(&parameter);
319 return_path = pf_map_path(pfm, goto_map->parts[0].start_tile);
321
322 if (return_path == NULL) {
323 log_goto_path(" no return path found");
324
325 if (p->start_tile == ptile) {
326 /* This mean we cannot reach the start point. It is probably,
327 * a path-finding bug, but don't make infinite recursion. */
328
329 if (!goto_warned) {
330 log_error("No path found to reach the start point.");
332 }
333
334 if (old_path != NULL) {
337 }
339 p->path = NULL;
344 }
345 return FALSE;
346 }
347
348 p->path = old_path;
349
350 if (p->path != NULL) {
352
353 p->end_tile = pos->tile;
354 p->end_moves_left = pos->moves_left;
355 p->end_fuel_left = pos->fuel_left;
356 }
357
360
361 return FALSE;
362 }
363
364 log_goto_path(" returned path found:");
365 pf_path_print(return_path, LOG_GOTO_PATH);
366
368 /* We cannot reuse old path because:
369 * 1- the start tile isn't the same.
370 * 2- the turn number neither (impossible to do in backward mode). */
373 }
374 goto_path_redraw(return_path, NULL);
375 goto_map->patrol.return_path = return_path;
376 }
377
380
381 log_goto_path("To (%d,%d) part %d: total_MC: %d",
382 TILE_XY(ptile), goto_map->num_parts,
385 : new_path)->total_MC);
386
387 return TRUE;
388}
389
390/************************************************************************/
395{
396 struct part *p = &goto_map->parts[goto_map->num_parts - 1];
397
398 if (NULL != p->path) {
399 /* Otherwise no need to update */
401 }
402}
403
404/************************************************************************/
407static void fill_parameter_part(struct pf_parameter *param,
408 const struct goto_map *goto_map,
409 const struct part *p)
410{
411 *param = goto_map->template;
412
413 if (p->start_tile == p->end_tile) {
414 /* Copy is enough, we didn't move last part. */
415 fc_assert(p->path->length == 1);
416 return;
417 }
418
419 param->start_tile = p->end_tile;
422 if (can_exist_at_tile(&(wld.map), param->utype, param->start_tile)) {
424 } else {
425 const struct unit *transporter =
427
430 }
431}
432
433/************************************************************************/
438static void add_part(struct goto_map *goto_map)
439{
440 struct part *p;
441 struct pf_parameter parameter;
442 struct unit *punit = goto_map_unit(goto_map);
443
445 goto_map->parts =
447 goto_map->num_parts * sizeof(*goto_map->parts));
448 p = &goto_map->parts[goto_map->num_parts - 1];
449
450 if (goto_map->num_parts == 1) {
451 /* first part */
453 parameter = goto_map->template;
454 } else {
455 struct part *prev = &goto_map->parts[goto_map->num_parts - 2];
456
457 p->start_tile = prev->end_tile;
458 fill_parameter_part(&parameter, goto_map, prev);
459 }
460 p->path = NULL;
461 p->end_tile = p->start_tile;
462 parameter.start_tile = p->start_tile;
463 p->map = pf_map_new(&parameter);
464}
465
466/************************************************************************/
470{
471 struct part *p = &goto_map->parts[goto_map->num_parts - 1];
472
474
476 if (p->path) {
477 /* We do not always have a path */
479 }
482}
483
484/************************************************************************/
488{
489 bool duplicate_of_last = TRUE;
490
492 if (NULL == goto_destination) {
493 /* Not a valid position. */
494 return FALSE;
495 }
496
498 const struct part *last_part = &goto_map->parts[goto_map->num_parts - 1];
499
500 if (last_part->path == NULL) {
501 /* The current part has zero length. */
502 return FALSE;
503 }
504 if (last_part->start_tile != last_part->end_tile) {
506 }
508 if (duplicate_of_last) {
509 return FALSE;
510 }
511
515
517 return TRUE;
518}
519
520/************************************************************************/
525{
526 bool popped = FALSE;
527
530 struct part *p = &goto_map->parts[goto_map->num_parts - 1];
531 struct tile *end_tile = p->end_tile;
532
533 if (goto_map->num_parts == 1) {
534 /* we don't have any waypoint but the start pos. */
535 continue;
536 }
537 popped = TRUE;
538
540
541 /*
542 * Set the end position of the previous part (now the last) to the
543 * end position of the last part (now gone). I.e. redraw a line to
544 * the mouse position.
545 */
546 update_last_part(goto_map, end_tile);
548 return popped;
549}
550
551/************************************************************************/
555static unsigned get_EC(const struct tile *ptile, enum known_type known,
556 const struct pf_parameter *param)
557{
558 return 1;
559}
560
561/************************************************************************/
565static enum tile_behavior get_TB_aggr(const struct tile *ptile,
566 enum known_type known,
567 const struct pf_parameter *param)
568{
569 if (known == TILE_UNKNOWN) {
571 return TB_IGNORE;
572 }
573 } else if (is_non_allied_unit_tile(ptile, param->owner)
574 || is_non_allied_city_tile(ptile, param->owner)) {
575 /* Can attack but can't count on going through */
576 return TB_DONT_LEAVE;
577 }
578 return TB_NORMAL;
579}
580
581/************************************************************************/
585static enum tile_behavior get_TB_caravan(const struct tile *ptile,
586 enum known_type known,
587 const struct pf_parameter *param)
588{
589 if (known == TILE_UNKNOWN) {
591 return TB_IGNORE;
592 }
593 } else if (is_non_allied_city_tile(ptile, param->owner)) {
594 /* Units that can establish a trade route, enter a market place or
595 * establish an embassy can travel to, but not through, enemy cities.
596 * FIXME: ACTION_HELP_WONDER units cannot. */
597 return TB_DONT_LEAVE;
598 } else if (is_non_allied_unit_tile(ptile, param->owner)) {
599 /* Note this must be below the city check. */
600 return TB_IGNORE;
601 }
602
603 /* Includes empty, allied, or allied-city tiles. */
604 return TB_NORMAL;
605}
606
607/************************************************************************/
611static int get_activity_time(const struct tile *ptile,
612 const struct player *pplayer)
613{
614 struct terrain *pterrain = tile_terrain(ptile);
615 int activity_mc = 0;
616
618
619 switch (connect_activity) {
621 if (pterrain->irrigation_time == 0) {
622 return -1;
623 }
624 extra_type_iterate(pextra) {
626 && tile_has_extra(ptile, pextra)) {
627 /* Don't replace old extras. */
628 return -1;
629 }
631
632 if (tile_has_extra(ptile, connect_tgt)) {
633 break;
634 }
635
636 activity_mc = pterrain->irrigation_time;
637 break;
640
641 if (!tile_has_extra(ptile, connect_tgt)) {
642 struct tile *vtile;
643 int single_mc;
644
645 vtile = tile_virtual_new(ptile);
648
649 if (single_mc < 0) {
650 return -1;
651 }
652
654 }
655 break;
656 default:
657 log_error("Invalid connect activity: %d.", connect_activity);
658 }
659
660 return activity_mc;
661}
662
663/************************************************************************/
667static bool is_non_allied_city_adjacent(const struct player *pplayer,
668 const struct tile *ptile)
669{
670 adjc_iterate(&(wld.map), ptile, tile1) {
671 if (is_non_allied_city_tile(tile1, pplayer)) {
672 return TRUE;
673 }
675
676 return FALSE;
677}
678
679/************************************************************************/
688static int get_connect_road(const struct tile *src_tile, enum direction8 dir,
689 const struct tile *dest_tile,
690 int src_cost, int src_extra,
691 unsigned *dest_cost, unsigned *dest_extra,
692 const struct pf_parameter *param)
693{
694 int activity_time, move_cost, moves_left;
695 int total_cost, total_extra;
696 struct road_type *proad;
697
698 if (tile_get_known(dest_tile, param->owner) == TILE_UNKNOWN) {
699 return -1;
700 }
701
702 activity_time = get_activity_time(dest_tile, param->owner);
703 if (activity_time < 0) {
704 return -1;
705 }
706
707 move_cost = param->get_MC(src_tile, PF_MS_NATIVE, dest_tile, PF_MS_NATIVE,
708 param);
710 return -1;
711 }
712
713 if (is_non_allied_city_adjacent(param->owner, dest_tile)) {
714 /* We don't want to build roads to enemies plus get ZoC problems */
715 return -1;
716 }
717
719
721
722 if (proad == NULL) {
723 /* No suitable road type available */
724 return -1;
725 }
726
727 /* Ok, the move is possible. What are the costs? */
728
729 /* Extra cost here is the final length of the road */
731
732 /* Special cases: get_MC function doesn't know that we would have built
733 * a road (railroad) on src tile by that time.
734 * We assume that settler building the road can also travel it. */
735 if (tile_has_road(dest_tile, proad)) {
736 move_cost = proad->move_cost;
737 }
738
739 move_cost = MIN(move_cost, param->move_rate);
740 total_cost = src_cost;
741 moves_left = param->move_rate - (src_cost % param->move_rate);
742 if (moves_left < move_cost) {
743 total_cost += moves_left;
744 } else {
745 total_cost += move_cost;
746 }
747
748 /* Now need to include the activity cost. If we have moves left, they
749 * will count as a full turn towards the activity time */
750 moves_left = param->move_rate - (total_cost % param->move_rate);
751 if (activity_time > 0) {
752 int speed = FC_PTR_TO_INT(param->data);
753
755 + (speed - 1)) / speed;
757 total_cost += moves_left;
758 }
759 total_cost += activity_time * param->move_rate;
760
761 /* Now we determine if we have found a better path. When building
762 * road type with positive move_cost, we care most about the length
763 * of the result. When building road type with move_cost 0, we
764 * care most about construction time. */
765
766 /* *dest_cost == -1 means we haven't reached dest until now */
767
768 if (*dest_cost != -1) {
769 if (proad->move_cost > 0) {
770 if (total_extra > *dest_extra
771 || (total_extra == *dest_extra && total_cost >= *dest_cost)) {
772 /* No, this path is worse than what we already have */
773 return -1;
774 }
775 } else {
776 if (total_cost > *dest_cost
777 || (total_cost == *dest_cost && total_extra >= *dest_extra)) {
778 return -1;
779 }
780 }
781 }
782
783 /* Ok, we found a better path! */
784 *dest_cost = total_cost;
786
787 return (proad->move_cost > 0 ?
788 total_extra * PF_TURN_FACTOR + total_cost :
789 total_cost * PF_TURN_FACTOR + total_extra);
790}
791
792/************************************************************************/
798static int get_connect_irrig(const struct tile *src_tile,
799 enum direction8 dir,
800 const struct tile *dest_tile,
801 int src_cost, int src_extra,
802 unsigned *dest_cost, unsigned *dest_extra,
803 const struct pf_parameter *param)
804{
805 int activity_time, move_cost, moves_left, total_cost;
806
807 if (tile_get_known(dest_tile, param->owner) == TILE_UNKNOWN) {
808 return -1;
809 }
810
811 activity_time = get_activity_time(dest_tile, param->owner);
812 if (activity_time < 0) {
813 return -1;
814 }
815
816 if (!is_cardinal_dir(dir)) {
817 return -1;
818 }
819
820 move_cost = param->get_MC(src_tile, PF_MS_NATIVE, dest_tile, PF_MS_NATIVE,
821 param);
823 return -1;
824 }
825
826 if (is_non_allied_city_adjacent(param->owner, dest_tile)) {
827 /* We don't want to build irrigation for enemies plus get ZoC problems */
828 return -1;
829 }
830
831 /* Ok, the move is possible. What are the costs? */
832
833 move_cost = MIN(move_cost, param->move_rate);
834 total_cost = src_cost;
835 moves_left = param->move_rate - (src_cost % param->move_rate);
836 if (moves_left < move_cost) {
837 total_cost += moves_left;
838 } else {
839 total_cost += move_cost;
840 }
841
842 /* Now need to include the activity cost. If we have moves left, they
843 * will count as a full turn towards the activity time */
844 moves_left = param->move_rate - (total_cost % param->move_rate);
845 if (activity_time > 0) {
846 int speed = FC_PTR_TO_INT(param->data);
847
849 + (speed - 1)) / speed;
851 total_cost += moves_left;
852 }
853 total_cost += activity_time * param->move_rate;
854
855 /* *dest_cost == -1 means we haven't reached dest until now */
856 if (*dest_cost != -1 && total_cost > *dest_cost) {
857 return -1;
858 }
859
860 /* Ok, we found a better path! */
861 *dest_cost = total_cost;
862 *dest_extra = 0;
863
864 return total_cost;
865}
866
867/************************************************************************/
871static enum tile_behavior
872no_fights_or_unknown_goto(const struct tile *ptile,
873 enum known_type known,
874 const struct pf_parameter *p)
875{
877 /* Special case allowing goto into the unknown. */
878 return TB_NORMAL;
879 }
880
881 return no_fights_or_unknown(ptile, known, p);
882}
883
884/************************************************************************/
888static void goto_fill_parameter_base(struct pf_parameter *parameter,
889 const struct unit *punit)
890{
891 pft_fill_unit_parameter(parameter, &(wld.map), punit);
892
893 fc_assert(parameter->get_EC == NULL);
894 fc_assert(parameter->get_TB == NULL);
895 fc_assert(parameter->get_MC != NULL);
896 fc_assert(parameter->start_tile == unit_tile(punit));
897 fc_assert(!parameter->omniscience);
898
899 parameter->get_EC = get_EC;
901 parameter->get_TB = get_TB_aggr;
904 parameter->get_TB = get_TB_caravan;
905 } else {
907 }
908}
909
910/************************************************************************/
922 const struct unit *punit)
923{
924 struct pf_parameter *parameter = &goto_map->template;
925
927
929
930 switch (hover_state) {
931 case HOVER_CONNECT:
932 {
934 int speed;
935
937 parameter->get_costs = get_connect_irrig;
938 } else {
939 parameter->get_costs = get_connect_road;
940 }
941 parameter->get_moves_left_req = NULL;
942
944 parameter->data = FC_INT_TO_PTR(speed);
945
946 /* Take into account the activity time at the origin */
949
950 if (activity_initial > 0) {
951 /* First action is activity */
952 parameter->moves_left_initially = parameter->move_rate;
953 /* Number of turns, rounding up */
956 if (punit->moves_left == 0) {
958 }
959 } else {
961 }
962 }
963 break;
964 case HOVER_GOTO:
965 case HOVER_PATROL:
968 /* TODO: consider doing the same for other actor consuming actions. */
969 /* We only want targets reachable immediately... */
970 parameter->move_rate = 0;
971 /* ...then we don't need to deal with dangers or refuel points. */
972 parameter->is_pos_dangerous = NULL;
973 parameter->get_moves_left_req = NULL;
974 } else {
976 }
977 break;
980 "Path finding during target selection");
981 break;
982 case HOVER_TELEPORT:
983 fc_assert_msg(hover_state != HOVER_TELEPORT, "Goto with HOVER_TELEPORT?");
984 break;
985 case HOVER_NONE:
986 case HOVER_PARADROP:
988 fc_assert_msg(hover_state != HOVER_NONE, "Goto with HOVER_NONE?");
990 "Goto with HOVER_PARADROP?");
992 "Goto with HOVER_ACT_SEL_TGT?");
993 break;
994 };
995}
996
997/************************************************************************/
1001void enter_goto_state(struct unit_list *punits)
1002{
1004
1005 /* Can't have selection rectangle and goto going on at the same time. */
1007
1010
1012
1017}
1018
1019/************************************************************************/
1023{
1024 if (!goto_is_active()) {
1025 return;
1026 }
1027
1032
1035}
1036
1037/************************************************************************/
1041{
1042 if (!goto_is_active()) {
1043 return;
1044 }
1045
1047 if (ptest == punit) {
1050 /* Stop now, links are gone! */
1051 break;
1052 }
1054}
1055
1056/************************************************************************/
1060{
1061 return (NULL != goto_maps && 0 != goto_map_list_size(goto_maps));
1062}
1063
1064/************************************************************************/
1068bool goto_get_turns(int *min, int *max)
1069{
1070 fc_assert_ret_val(min != NULL, FALSE);
1071 fc_assert_ret_val(max != NULL, FALSE);
1072
1073 *min = FC_INFINITY;
1074 *max = -1;
1075
1076 if (!goto_is_active()) {
1077 return FALSE;
1078 }
1079 if (NULL == goto_destination) {
1080 /* Not a valid position. */
1081 return FALSE;
1082 }
1083
1084 if (hover_state == HOVER_CONNECT) {
1085 /* In connect mode, we want to know the turn number the activity will
1086 * be finished. */
1088
1090 bool moved = FALSE;
1091 int turns = goto_map->connect.initial_turns;
1092 int i;
1093
1094 for (i = 0; i < goto_map->num_parts; i++) {
1095 const struct pf_path *path = goto_map->parts[i].path;
1096
1098 if (!moved && path->length > 1) {
1099 moved = TRUE;
1100 }
1101 }
1102
1103 if (moved && activity_time > 0) {
1104 turns++;
1105 }
1106
1107 if (turns < *min) {
1108 *min = turns;
1109 }
1110 if (turns > *max) {
1111 *max = turns;
1112 }
1114 } else {
1115 /* In other modes, we want to know the turn number to reach the tile. */
1117 int turns = 0;
1118 int i;
1119
1120 for (i = 0; i < goto_map->num_parts; i++) {
1122 }
1126 }
1127
1128 if (turns < *min) {
1129 *min = turns;
1130 }
1131 if (turns > *max) {
1132 *max = turns;
1133 }
1135 }
1136
1137 return TRUE;
1138}
1139
1140/************************************************************************/
1144bool goto_tile_state(const struct tile *ptile, enum goto_tile_state *state,
1145 int *turns, bool *waypoint)
1146{
1147 fc_assert_ret_val(ptile != NULL, FALSE);
1148 fc_assert_ret_val(turns != NULL, FALSE);
1149 fc_assert_ret_val(waypoint != NULL, FALSE);
1150
1151 if (!goto_is_active()) {
1152 return FALSE;
1153 }
1154
1155 *state = -1;
1156 *turns = -1;
1157 *waypoint = FALSE;
1158
1159 if (hover_state == HOVER_CONNECT) {
1160 /* In connect mode, we want to know the turn number the activity will
1161 * be finished. */
1162 int activity_time;
1163
1164 if (tile_get_known(ptile, client_player()) == TILE_UNKNOWN) {
1165 return FALSE; /* We never connect on unknown tiles. */
1166 }
1167
1169
1171 const struct pf_path *path;
1172 const struct pf_position *pos = NULL; /* Keep compiler happy! */
1174 int turns_for_map = -2;
1175 bool moved = FALSE;
1176 int i, j;
1177
1178 for (i = 0; i < goto_map->num_parts; i++) {
1179 if (i > 0 && goto_map->parts[i].start_tile == ptile) {
1180 *waypoint = TRUE;
1181 }
1182
1183 path = goto_map->parts[i].path;
1184 if (path == NULL || path->length == 0) {
1185 continue;
1186 }
1187
1188 for (j = 0; j < path->length; j++) {
1189 pos = path->positions + j;
1190 if (!moved && j > 0) {
1191 moved = TRUE;
1192 }
1193 if (pos->tile != ptile) {
1194 continue;
1195 }
1196 if (activity_time > 0) {
1197 if (map_turns + pos->turn + moved > turns_for_map) {
1198 turns_for_map = map_turns + pos->turn + moved;
1199 }
1200 } else if (pos->moves_left == 0) {
1201 if (map_turns + pos->turn > turns_for_map) {
1202 turns_for_map = map_turns + pos->turn + moved;
1203 }
1204 }
1205 }
1206 map_turns += pos->turn;
1207 }
1208
1209 if (ptile == goto_destination) {
1210 int ml = (pos != NULL ? pos->moves_left : 0);
1211
1212 if (moved && activity_time > 0) {
1213 map_turns++;
1214 }
1215 if (map_turns > *turns) {
1216 *state = (activity_time > 0 || ml == 0
1218 *turns = map_turns;
1219 } else if (map_turns == *turns
1220 && *state == GTS_MP_LEFT
1221 && (activity_time > 0 || ml == 0)) {
1222 *state = GTS_EXHAUSTED_MP;
1223 }
1224 } else {
1225 if (activity_time > 0) {
1226 if (turns_for_map > *turns) {
1227 *state = GTS_TURN_STEP;
1228 *turns = turns_for_map;
1229 }
1230 } else {
1231 if (turns_for_map + 1 > *turns) {
1232 *state = GTS_TURN_STEP;
1233 *turns = turns_for_map + 1;
1234 }
1235 }
1236 }
1238 } else {
1239 bool mark_on_map = FALSE;
1240
1241 /* In other modes, we want to know the turn number to reach the tile. */
1243 const struct tile *destination;
1244 const struct pf_path *path;
1245 const struct pf_position *pos = NULL; /* Keep compiler happy! */
1246 const struct pf_position *last_pos = NULL;
1247 int map_turns = 0;
1248 int turns_for_map = -2;
1249 int i, j;
1250
1251 for (i = 0; i < goto_map->num_parts; i++) {
1252 if (i > 0 && goto_map->parts[i].start_tile == ptile) {
1253 mark_on_map = *waypoint = TRUE;
1254 }
1255
1256 path = goto_map->parts[i].path;
1257 if (path == NULL || path->length == 0) {
1258 continue;
1259 }
1260 last_pos = path->positions;
1261 for (j = 0; j < path->length; j++) {
1262 pos = path->positions + j;
1263 /* turn to reach was increased in that step */
1264 if (pos->turn != last_pos->turn
1265 && pos->tile == ptile) {
1266 mark_on_map = TRUE;
1267 }
1268 if (pos->moves_left == 0 && last_pos->moves_left != 0
1269 && pos->tile == ptile) {
1270 mark_on_map = TRUE;
1271 }
1272 if (pos->tile == ptile
1273 /* End turn case. */
1274 && (pos->moves_left == 0
1275 /* Waiting case. */
1276 || (j < path->length - 1 && (pos + 1)->tile == ptile))
1277 && map_turns + pos->turn > turns_for_map) {
1278 turns_for_map = map_turns + pos->turn;
1279 }
1280 last_pos = pos;
1281 }
1282 map_turns += pos->turn;
1283 }
1284
1287 && goto_map->patrol.return_path->length > 0) {
1288 path = goto_map->patrol.return_path;
1289
1290 for (j = 0; j < path->length; j++) {
1291 pos = path->positions + j;
1292 if (pos->tile == ptile
1293 /* End turn case. */
1294 && (pos->moves_left == 0
1295 /* Waiting case. */
1296 || (j < path->length - 1 && (pos + 1)->tile == ptile))
1297 && map_turns + pos->turn > turns_for_map) {
1298 turns_for_map = map_turns + pos->turn;
1299 }
1300 }
1301 map_turns += pos->turn;
1302 destination = pos->tile;
1303 } else {
1305 }
1306
1307 if (ptile == destination) {
1308 int ml = (pos != NULL ? pos->moves_left : 0);
1309
1310 if (map_turns > *turns) {
1311 mark_on_map = TRUE;
1312 *state = (ml == 0 ? GTS_EXHAUSTED_MP : GTS_MP_LEFT);
1313 *turns = map_turns;
1314 } else if (map_turns == *turns
1315 && *state == GTS_MP_LEFT
1316 && ml == 0) {
1317 *state = GTS_EXHAUSTED_MP;
1318 }
1319 } else {
1320 if (turns_for_map > *turns) {
1321 *state = GTS_TURN_STEP;
1322 *turns = turns_for_map;
1323 }
1324 }
1326
1327 return mark_on_map;
1328 }
1329
1330 return (*turns != -1 || *waypoint);
1331}
1332
1333/************************************************************************/
1338bool is_valid_goto_draw_line(struct tile *dest_tile)
1339{
1341 if (NULL == dest_tile) {
1342 return FALSE;
1343 }
1344
1345 /* assume valid destination */
1346 goto_destination = dest_tile;
1347
1349 if (!update_last_part(goto_map, dest_tile)) {
1351 }
1353
1354 /* Update goto data in info label. */
1356 return (NULL != goto_destination);
1357}
1358
1359/************************************************************************/
1364{
1365 struct packet_unit_orders p;
1366
1367 if (!can_client_issue_orders()) {
1368 return;
1369 }
1370
1371 /* Clear the orders by sending an empty orders path. */
1372 log_goto_packet("Clearing orders for unit %d.", punit->id);
1373 p.unit_id = punit->id;
1375 p.repeat = p.vigilant = FALSE;
1376 p.length = 0;
1380}
1381
1382/************************************************************************/
1385static void make_path_orders(struct unit *punit, struct pf_path *path,
1386 enum unit_orders orders,
1387 struct unit_order *final_order,
1388 struct unit_order *order_list,
1389 int *length, int *dest_tile)
1390{
1391 int i;
1392 struct tile *old_tile;
1393
1394 fc_assert_ret(path != NULL);
1396 "Unit %d has moved without goto cancellation.",
1397 punit->id);
1398 fc_assert_ret(length != NULL);
1399
1400 /* We skip the start position. */
1401 *length = path->length - 1;
1402 fc_assert(*length < MAX_LEN_ROUTE);
1403 old_tile = path->positions[0].tile;
1404
1405 /* If the path has n positions it takes n-1 steps. */
1406 for (i = 0; i < path->length - 1; i++) {
1407 struct tile *new_tile = path->positions[i + 1].tile;
1408
1409 if (same_pos(new_tile, old_tile)) {
1410 order_list[i].order = ORDER_FULL_MP;
1411 order_list[i].dir = DIR8_ORIGIN;
1412 order_list[i].activity = ACTIVITY_LAST;
1413 order_list[i].target = NO_TARGET;
1414 order_list[i].sub_target = NO_TARGET;
1415 order_list[i].action = ACTION_NONE;
1416 log_goto_packet(" packet[%d] = wait: %d,%d", i, TILE_XY(old_tile));
1417 } else {
1418 order_list[i].order = orders;
1420 order_list[i].activity = ACTIVITY_LAST;
1421 order_list[i].target = NO_TARGET;
1422 order_list[i].sub_target = NO_TARGET;
1423 order_list[i].action = ACTION_NONE;
1424 log_goto_packet(" packet[%d] = move %s: %d,%d => %d,%d",
1425 i, dir_get_name(order_list[i].dir),
1427 }
1429 }
1430
1431 if (i > 0
1432 && order_list[i - 1].order == ORDER_MOVE
1435 /* Won't be able to perform a regular move to the target tile... */
1436 if (!final_order) {
1437 /* ...and no final order exists. Choose what to do when the unit gets
1438 * there. */
1439 order_list[i - 1].order = ORDER_ACTION_MOVE;
1440 } else {
1441 /* ...and a final order exist. Can't assume an action move. Did the
1442 * caller hope that the situation would change before the unit got
1443 * there? */
1444
1445 /* It's currently illegal to walk into tiles with non-allied units or
1446 * cities. Some actions causes the actor to enter the target tile but
1447 * that is a part of the action it self, not a regular pre action
1448 * move. */
1449 log_verbose("unit or city blocks the path of your %s",
1451 }
1452 }
1453
1454 if (final_order) {
1455 /* Append the final order after moving to the target tile. */
1456 order_list[i].order = final_order->order;
1457 order_list[i].dir = final_order->dir;
1458 order_list[i].activity = (final_order->order == ORDER_ACTIVITY)
1459 ? final_order->activity : ACTIVITY_LAST;
1460 order_list[i].target = final_order->target;
1461 order_list[i].sub_target = final_order->sub_target;
1462 order_list[i].action = final_order->action;
1463 (*length)++;
1464 }
1465
1466 if (dest_tile) {
1467 *dest_tile = tile_index(old_tile);
1468 }
1469}
1470
1471/************************************************************************/
1474static void send_path_orders(struct unit *punit, struct pf_path *path,
1475 bool repeat, bool vigilant,
1476 enum unit_orders orders,
1477 struct unit_order *final_order)
1478{
1479 struct packet_unit_orders p;
1480
1481 if (path->length == 1 && final_order == NULL) {
1482 return; /* No path at all, no need to spam the server. */
1483 }
1484
1485 memset(&p, 0, sizeof(p));
1486 p.unit_id = punit->id;
1488 p.repeat = repeat;
1489 p.vigilant = vigilant;
1490
1491 log_goto_packet("Orders for unit %d:", punit->id);
1492 log_goto_packet(" Repeat: %d. Vigilant: %d.",
1493 p.repeat, p.vigilant);
1494
1496 p.orders, &p.length, &p.dest_tile);
1497
1500}
1501
1502/************************************************************************/
1505static void send_rally_path_orders(struct city *pcity, struct unit *punit,
1506 struct pf_path *path, bool vigilant,
1507 bool persistent,
1508 enum unit_orders orders,
1509 struct unit_order *final_order)
1510{
1511 struct packet_city_rally_point p;
1512
1513 memset(&p, 0, sizeof(p));
1514 p.id = pcity->id;
1515 p.vigilant = vigilant;
1517
1518 log_goto_packet("Rally orders for city %d:", pcity->id);
1519 log_goto_packet(" Vigilant: %d.", p.vigilant);
1520
1522 p.orders, &p.length, NULL);
1523
1525}
1526
1527/************************************************************************/
1530void send_goto_path(struct unit *punit, struct pf_path *path,
1531 struct unit_order *final_order)
1532{
1534}
1535
1536/************************************************************************/
1539static void send_rally_path(struct city *pcity, struct unit *punit,
1540 bool persistent, struct pf_path *path,
1541 struct unit_order *final_order)
1542{
1545}
1546
1547/************************************************************************/
1551bool send_goto_tile(struct unit *punit, struct tile *ptile)
1552{
1553 struct pf_parameter parameter;
1554 struct pf_map *pfm;
1555 struct pf_path *path;
1556
1557 goto_fill_parameter_base(&parameter, punit);
1558 pfm = pf_map_new(&parameter);
1559 path = pf_map_path(pfm, ptile);
1561
1562 if (path) {
1563 send_goto_path(punit, path, NULL);
1564 pf_path_destroy(path);
1565 return TRUE;
1566 } else {
1567 return FALSE;
1568 }
1569}
1570
1571/************************************************************************/
1575bool send_rally_tile(struct city *pcity, struct tile *ptile, bool persistent)
1576{
1577 const struct unit_type *putype;
1578 struct unit *punit;
1579 struct pf_parameter parameter;
1580 struct pf_map *pfm;
1581 struct pf_path *path;
1582
1583 fc_assert_ret_val(pcity != NULL, FALSE);
1584 fc_assert_ret_val(ptile != NULL, FALSE);
1585
1586 /* Create a virtual unit of the type being produced by the city. */
1587 if (pcity->production.kind != VUT_UTYPE) {
1588 /* Can only give orders to units. */
1589 return FALSE;
1590 }
1591
1592 putype = pcity->production.value.utype;
1595 putype));
1596
1597 /* Use the unit to find a path to the destination tile. */
1598 goto_fill_parameter_base(&parameter, punit);
1599 pfm = pf_map_new(&parameter);
1600 path = pf_map_path(pfm, ptile);
1602
1603 if (path) {
1604 /* Send orders to server. */
1605 send_rally_path(pcity, punit, persistent, path, NULL);
1607 pf_path_destroy(path);
1608
1609 return TRUE;
1610 } else {
1612
1613 return FALSE;
1614 }
1615}
1616
1617/************************************************************************/
1621bool send_attack_tile(struct unit *punit, struct tile *ptile)
1622{
1623 struct pf_parameter parameter;
1624 struct pf_map *pfm;
1625 struct pf_path *path;
1626
1627 goto_fill_parameter_base(&parameter, punit);
1628 parameter.move_rate = 0;
1629 parameter.is_pos_dangerous = NULL;
1630 parameter.get_moves_left_req = NULL;
1631 pfm = pf_map_new(&parameter);
1632 path = pf_map_path(pfm, ptile);
1634
1635 if (path) {
1636 send_path_orders(punit, path, false, false, ORDER_ACTION_MOVE, NULL);
1637 pf_path_destroy(path);
1638 return TRUE;
1639 }
1640 return FALSE;
1641}
1642
1643/************************************************************************/
1648{
1651 int i;
1652 struct pf_path *path = NULL;
1653 struct part *last_part = &goto_map->parts[goto_map->num_parts - 1];
1654
1655 if (NULL == last_part->path) {
1656 /* Cannot move there */
1657 continue;
1658 }
1659
1660 for (i = 0; i < goto_map->num_parts; i++) {
1662 }
1664
1666
1669}
1670
1671/************************************************************************/
1674static bool order_recursive_roads(struct tile *ptile, struct extra_type *pextra,
1675 struct packet_unit_orders *p, int rec)
1676{
1677 if (rec > MAX_EXTRA_TYPES) {
1678 return FALSE;
1679 }
1680
1681 if (!is_extra_caused_by(pextra, EC_ROAD)) {
1682 return FALSE;
1683 }
1684
1685 if (tile_has_extra(ptile, pextra)) {
1686 /* No need to build what is already there. */
1687 return TRUE;
1688 }
1689
1690 extra_deps_iterate(&(pextra->reqs), pdep) {
1691 if (!tile_has_extra(ptile, pdep)) {
1692 if (!order_recursive_roads(ptile, pdep, p, rec + 1)) {
1693 return FALSE;
1694 }
1695 }
1697
1699 p->orders[p->length].dir = DIR8_ORIGIN;
1701 p->orders[p->length].target = ptile->index;
1702 p->orders[p->length].sub_target = extra_index(pextra);
1704 p->length++;
1705
1706 return TRUE;
1707}
1708
1709/************************************************************************/
1714 struct extra_type *tgt)
1715{
1718 int i;
1719 struct packet_unit_orders p;
1720 struct tile *old_tile;
1721 struct pf_path *path = NULL;
1722 struct part *last_part = &goto_map->parts[goto_map->num_parts - 1];
1723
1724 if (NULL == last_part->path) {
1725 /* Cannot move there */
1726 continue;
1727 }
1728
1729 memset(&p, 0, sizeof(p));
1730
1731 i = 0;
1732 do {
1734 i++;
1735 } while (i < goto_map->num_parts);
1736
1737 p.unit_id = punit->id;
1739 p.repeat = FALSE;
1740 p.vigilant = FALSE; /* Should be TRUE? */
1741
1742 p.length = 0;
1744
1745 for (i = 0; i < path->length; i++) {
1746 switch (activity) {
1747 case ACTIVITY_IRRIGATE:
1748 if (!tile_has_extra(old_tile, tgt)) {
1749 /* Assume the unit can irrigate or we wouldn't be here. */
1753 p.orders[p.length].target = old_tile->index;
1754 p.orders[p.length].sub_target = extra_index(tgt);
1756 p.length++;
1757 }
1758 break;
1759 case ACTIVITY_GEN_ROAD:
1760 order_recursive_roads(old_tile, tgt, &p, 0);
1761 break;
1762 default:
1763 log_error("Invalid connect activity: %d.", activity);
1764 break;
1765 }
1766
1767 if (i != path->length - 1) {
1768 struct tile *new_tile = path->positions[i + 1].tile;
1769
1771
1779 p.length++;
1780
1782 }
1783 }
1784
1786
1790}
1791
1792/************************************************************************/
1799static bool order_wants_direction(enum unit_orders order, action_id act_id,
1800 struct tile *tgt_tile)
1801{
1802 switch (order) {
1803 case ORDER_MOVE:
1804 case ORDER_ACTION_MOVE:
1805 /* Not only is it legal. It is mandatory. A move is always done in a
1806 * direction. */
1807 return TRUE;
1809 if (!action_id_distance_accepted(act_id, 0)) {
1810 /* Always illegal to do to a target on the actor's own tile. */
1811 return TRUE;
1812 }
1813
1814 if (!action_id_distance_accepted(act_id, 1)) {
1815 /* Always illegal to perform to a target on a neighbor tile. */
1816 return FALSE;
1817 }
1818
1821 /* Won't be able to move to the target tile to perform the action on
1822 * top of it. */
1823 /* TODO: Detect situations where it also would be illegal to perform
1824 * the action from the neighbor tile. */
1825 return TRUE;
1826 }
1827
1829 /* Prefer efficiency over safety among allies. */
1831 return TRUE;
1832 }
1833
1834 return FALSE;
1835 default:
1836 return FALSE;
1837 }
1838}
1839
1840/************************************************************************/
1844static bool order_demands_direction(enum unit_orders order, action_id act_id)
1845{
1846 switch (order) {
1847 case ORDER_MOVE:
1848 case ORDER_ACTION_MOVE:
1849 /* A move is always done in a direction. */
1850 return TRUE;
1852 if (!action_id_distance_accepted(act_id, 0)) {
1853 /* Always illegal to do to a target on the actor's own tile. */
1854 return TRUE;
1855 }
1856
1857 return FALSE;
1858 default:
1859 return FALSE;
1860 }
1861}
1862
1863/************************************************************************/
1870{
1873 int i;
1874 struct tile *tgt_tile;
1875 struct pf_path *path = NULL;
1876 struct part *last_part = &goto_map->parts[goto_map->num_parts - 1];
1877
1878 if (NULL == last_part->path) {
1879 /* Cannot move there */
1880 continue;
1881 }
1882
1883 i = 0;
1884 do {
1886 i++;
1887 } while (i < goto_map->num_parts);
1888
1890
1892
1893 /* Make the last move in a plain goto try to pop up the action
1894 * selection dialog rather than moving to the last tile if it contains
1895 * a domestic, allied or team mate city, unit or unit stack. This can,
1896 * in cases where the action requires movement left, save a turn. */
1902 ACTION_ANY,
1904 FALSE)
1906 ACTION_ANY,
1908 TRUE)
1910 ACTION_ANY,
1911 DS_TEAM,
1912 TRUE)))) {
1913 /* Try to pop up the action selection dialog before moving to the
1914 * target tile. */
1916 }
1917
1918 /* Handle single-step goto like single-step move. */
1919 if (goto_last_order == ORDER_LAST && path->length == 2
1922 }
1923
1924 if (goto_last_order == ORDER_LAST) {
1926 } else if (path->length > 1
1929 struct unit_order order;
1930 int last_order_dir;
1931 struct tile *on_tile;
1933
1934 if (path->length > 1 && goto_last_tgt == NO_TARGET
1935 && ((on_tile = path->positions[path->length - 2].tile))
1937 tgt_tile)
1938 && !same_pos(on_tile, tgt_tile)) {
1939 /* The last order prefers to handle the last direction it self.
1940 * There exists a tile before the target tile to do it from. */
1941
1942 /* Give the last path direction to the final order. */
1944
1945 /* The last path direction is now spent. */
1947 } else {
1951
1952 /* Target the tile the actor is standing on or goto_last_tgt. */
1954 }
1955
1958 ? tgt_tile->index : goto_last_tgt);
1960 }
1961
1962 order.order = goto_last_order;
1963 order.dir = last_order_dir;
1964 order.activity = ACTIVITY_LAST;
1965 order.target = last_order_target;
1967 order.action = goto_last_action;
1968
1969 /* ORDER_ACTIVITY would require real activity */
1971
1972 send_goto_path(punit, path, &order);
1973 }
1974 pf_path_destroy(path);
1976}
1977
1978/************************************************************************/
1983{
1984 struct pf_parameter parameter;
1985 struct pf_map *pfm;
1986 struct pf_path *path = NULL;
1987
1989 /* We're already on a city - don't go anywhere. */
1990 return NULL;
1991 }
1992
1993 goto_fill_parameter_base(&parameter, punit);
1994 pfm = pf_map_new(&parameter);
1995
1996 pf_map_tiles_iterate(pfm, ptile, FALSE) {
1997 if (is_allied_city_tile(ptile, unit_owner(punit))) {
1998 path = pf_map_path(pfm, ptile);
1999 break;
2000 }
2002
2004
2005 return path;
2006}
2007
2008/************************************************************************/
2011struct tile *tile_before_end_path(struct unit *punit, struct tile *ptile)
2012{
2013 struct pf_parameter parameter;
2014 struct pf_map *pfm;
2015 struct tile *dtile;
2016 struct pf_path *path;
2017
2018 goto_fill_parameter_base(&parameter, punit);
2019 parameter.move_rate = 0;
2020 parameter.is_pos_dangerous = NULL;
2021 parameter.get_moves_left_req = NULL;
2022 pfm = pf_map_new(&parameter);
2023 path = pf_map_path(pfm, ptile);
2024 if (path == NULL) {
2025 return NULL;
2026 }
2027 if (path->length < 2) {
2028 dtile = NULL;
2029 } else {
2030 dtile = path->positions[path->length - 2].tile;
2031 }
2033
2034 return dtile;
2035}
bool action_id_exists(const action_id act_id)
Definition actions.c:1829
#define action_id_distance_accepted(act_id, distance)
Definition actions.h:684
#define ACTION_ANY
Definition actions.h:308
#define action_id_has_result_safe(act_id, result)
Definition actions.h:665
#define ACTION_NONE
Definition actions.h:311
#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:770
static bool is_allied_city_tile(const struct tile *ptile, const struct player *pplayer)
Definition city.h:746
struct civclient client
bool can_client_issue_orders(void)
#define client_player()
char * incite_cost
Definition comments.c:75
#define MAX_LEN_ROUTE
Definition conn_types.h:38
bool unit_is_in_focus(const struct unit *punit)
Definition control.c:388
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:1337
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:2128
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:481
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:354
#define DIR8_ORIGIN
Definition fc_types.h:457
int action_id
Definition fc_types.h:389
#define MAX_EXTRA_TYPES
Definition fc_types.h:50
struct world wld
Definition game.c:63
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:667
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:798
static void fill_parameter_part(struct pf_parameter *param, const struct goto_map *goto_map, const struct part *p)
Definition goto.c:407
#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:688
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:1385
static void goto_path_undraw(const struct pf_path *path)
Definition goto.c:236
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:872
static bool order_recursive_roads(struct tile *ptile, struct extra_type *pextra, struct packet_unit_orders *p, int rec)
Definition goto.c:1674
static void goto_fill_parameter_full(struct goto_map *goto_map, const struct unit *punit)
Definition goto.c:921
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:555
static enum tile_behavior get_TB_caravan(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
Definition goto.c:585
void exit_goto_state(void)
Definition goto.c:1022
struct tile * tile_before_end_path(struct unit *punit, struct tile *ptile)
Definition goto.c:2011
bool goto_is_active(void)
Definition goto.c:1059
bool send_attack_tile(struct unit *punit, struct tile *ptile)
Definition goto.c:1621
struct pf_path * path_to_nearest_allied_city(struct unit *punit)
Definition goto.c:1982
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:888
void init_client_goto(void)
Definition goto.c:152
#define goto_map_unit_iterate_end
Definition goto.c:88
void send_patrol_route(void)
Definition goto.c:1647
bool send_rally_tile(struct city *pcity, struct tile *ptile, bool persistent)
Definition goto.c:1575
static bool order_wants_direction(enum unit_orders order, action_id act_id, struct tile *tgt_tile)
Definition goto.c:1799
static void remove_last_part(struct goto_map *goto_map)
Definition goto.c:469
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:1505
bool is_valid_goto_draw_line(struct tile *dest_tile)
Definition goto.c:1338
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:1474
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:258
static enum tile_behavior get_TB_aggr(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
Definition goto.c:565
#define goto_map_list_iterate(gotolist, pgoto)
Definition goto.c:78
static void reset_last_part(struct goto_map *goto_map)
Definition goto.c:394
#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:487
bool send_goto_tile(struct unit *punit, struct tile *ptile)
Definition goto.c:1551
static struct unit * goto_map_unit(const struct goto_map *goto_map)
Definition goto.c:139
bool goto_pop_waypoint(void)
Definition goto.c:524
#define log_goto_packet
Definition goto.c:45
void send_connect_route(enum unit_activity activity, struct extra_type *tgt)
Definition goto.c:1713
void goto_unit_killed(struct unit *punit)
Definition goto.c:1040
void free_client_goto(void)
Definition goto.c:162
void enter_goto_state(struct unit_list *punits)
Definition goto.c:1001
void send_goto_route(void)
Definition goto.c:1869
bool is_valid_goto_destination(const struct tile *ptile)
Definition goto.c:179
static void goto_path_redraw(const struct pf_path *new_path, const struct pf_path *old_path)
Definition goto.c:187
bool goto_get_turns(int *min, int *max)
Definition goto.c:1068
static int get_activity_time(const struct tile *ptile, const struct player *pplayer)
Definition goto.c:611
static void goto_map_free(struct goto_map *goto_map)
Definition goto.c:122
void request_orders_cleared(struct unit *punit)
Definition goto.c:1363
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:1539
static bool order_demands_direction(enum unit_orders order, action_id act_id)
Definition goto.c:1844
void send_goto_path(struct unit *punit, struct pf_path *path, struct unit_order *final_order)
Definition goto.c:1530
static void add_part(struct goto_map *goto_map)
Definition goto.c:438
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:1347
const char * dir_get_name(enum direction8 dir)
Definition map.c:1146
bool is_cardinal_dir(enum direction8 dir)
Definition map.c:1316
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Definition map.c:940
bool is_valid_dir(enum direction8 dir)
Definition map.c:1260
#define adjc_iterate_end
Definition map.h:433
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:428
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:290
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:840
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:160
bool popup_last_move_to_allied
Definition options.h:170
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:222
Definition tile.h:50
int index
Definition tile.h:51
enum unit_activity activity
Definition unit.h:94
enum unit_orders order
Definition unit.h:93
int action
Definition unit.h:100
enum direction8 dir
Definition unit.h:102
int target
Definition unit.h:97
int sub_target
Definition unit.h:98
Definition unit.h:138
int moves_left
Definition unit.h:150
int id
Definition unit.h:145
struct unit * transporter
Definition unit.h:183
enum universals_n kind
Definition fc_types.h:902
universals_u value
Definition fc_types.h:901
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:1033
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:88
known_type
Definition tile.h:35
@ TILE_UNKNOWN
Definition tile.h:36
#define ACTIVITY_FACTOR
Definition tile.h:165
#define tile_terrain(_tile)
Definition tile.h:110
#define TILE_XY(ptile)
Definition tile.h:43
#define tile_has_extra(ptile, pextra)
Definition tile.h:147
const struct unit_type * utype
Definition fc_types.h:721
struct unit * transporter_for_unit_at(const struct unit *pcargo, const struct tile *ptile)
Definition unit.c:1922
int get_activity_rate(const struct unit *punit)
Definition unit.c:495
struct unit * unit_virtual_create(struct player *pplayer, struct city *pcity, const struct unit_type *punittype, int veteran_level)
Definition unit.c:1624
void unit_virtual_destroy(struct unit *punit)
Definition unit.c:1729
#define unit_tile(_pu)
Definition unit.h:397
unit_orders
Definition unit.h:37
@ ORDER_ACTION_MOVE
Definition unit.h:45
@ ORDER_ACTIVITY
Definition unit.h:41
@ ORDER_FULL_MP
Definition unit.h:43
@ ORDER_MOVE
Definition unit.h:39
@ ORDER_LAST
Definition unit.h:49
@ ORDER_PERFORM_ACTION
Definition unit.h:47
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)
Definition unit.h:432
#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 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