webperimental: killstack decides stack protects.
[freeciv.git] / client / goto.c
blob5fd7498c0381ed6a6b58d993d00efcfff5912959
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.
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 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 #include <string.h>
20 /* utility */
21 #include "log.h"
22 #include "mem.h"
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"
34 /* client/include */
35 #include "client_main.h"
36 #include "control.h"
37 #include "mapview_g.h"
39 /* client */
40 #include "goto.h"
41 #include "mapctrl_common.h"
43 #define LOG_GOTO_PATH LOG_DEBUG
44 #define log_goto_path log_debug
45 #define log_goto_packet log_debug
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.
52 struct part {
53 struct tile *start_tile, *end_tile;
54 int end_moves_left, end_fuel_left;
55 struct pf_path *path;
56 struct pf_map *map;
59 struct goto_map {
60 struct unit *focus;
61 struct part *parts;
62 int num_parts;
63 union {
64 struct {
65 int initial_turns;
66 } connect;
67 struct {
68 struct pf_path *return_path;
69 } patrol;
71 struct pf_parameter template;
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
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);
88 #define goto_map_unit_iterate_end \
89 } goto_map_list_iterate_end;
91 static struct goto_map_list *goto_maps = NULL;
92 static bool goto_warned = FALSE;
94 static void reset_last_part(struct goto_map *goto_map);
95 static void remove_last_part(struct goto_map *goto_map);
96 static void fill_parameter_part(struct pf_parameter *param,
97 const struct goto_map *goto_map,
98 const struct part *p);
100 /**************************************************************************
101 Various stuff for the goto routes
102 **************************************************************************/
103 static struct tile *goto_destination = NULL;
105 /****************************************************************************
106 Create a new goto map.
107 ****************************************************************************/
108 static struct goto_map *goto_map_new(struct unit *punit)
110 struct goto_map *goto_map = fc_malloc(sizeof(*goto_map));
112 goto_map->focus = punit;
113 goto_map->parts = NULL;
114 goto_map->num_parts = 0;
116 return goto_map;
119 /****************************************************************************
120 Free an existing goto map.
121 ****************************************************************************/
122 static void goto_map_free(struct goto_map *goto_map)
124 if (NULL != goto_map->parts) {
125 while (goto_map->num_parts > 0) {
126 remove_last_part(goto_map);
128 free(goto_map->parts);
130 if (hover_state == HOVER_PATROL && goto_map->patrol.return_path) {
131 pf_path_destroy(goto_map->patrol.return_path);
133 free(goto_map);
136 /****************************************************************************
137 Returns the unit associated with the goto map.
138 ****************************************************************************/
139 static struct unit *goto_map_unit(const struct goto_map *goto_map)
141 struct unit *punit = goto_map->focus;
143 fc_assert(punit != NULL);
144 fc_assert(unit_is_in_focus(punit));
145 fc_assert(punit == player_unit_by_number(client_player(), punit->id));
146 return punit;
149 /**********************************************************************
150 Called only by handle_map_info() in client/packhand.c.
151 ***********************************************************************/
152 void init_client_goto(void)
154 free_client_goto();
156 goto_maps = goto_map_list_new();
159 /**********************************************************************
160 Called above, and by control_done() in client/control.c.
161 ***********************************************************************/
162 void free_client_goto(void)
164 if (NULL != goto_maps) {
165 goto_map_list_iterate(goto_maps, goto_map) {
166 goto_map_free(goto_map);
167 } goto_map_list_iterate_end;
168 goto_map_list_destroy(goto_maps);
169 goto_maps = NULL;
172 goto_destination = NULL;
173 goto_warned = FALSE;
176 /**********************************************************************
177 Determines if a goto to the destination tile is allowed.
178 ***********************************************************************/
179 bool is_valid_goto_destination(const struct tile *ptile)
181 return (NULL != goto_destination && ptile == goto_destination);
184 /****************************************************************************
185 Show goto lines.
186 ****************************************************************************/
187 static void goto_path_redraw(const struct pf_path *new_path,
188 const struct pf_path *old_path)
190 int start_index = 0;
191 int i;
193 fc_assert_ret(new_path != NULL);
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;
202 if (old_pos->dir_to_next_pos != new_pos->dir_to_next_pos
203 || old_pos->tile != new_pos->tile) {
204 break;
207 start_index = i;
209 /* Erase everything we cannot reuse. */
210 for (; i < old_path->length - 1; i++) {
211 struct pf_position *pos = old_path->positions + i;
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);
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;
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);
233 /****************************************************************************
234 Remove goto lines.
235 ****************************************************************************/
236 static void goto_path_undraw(const struct pf_path *path)
238 int i;
240 fc_assert_ret(path != NULL);
242 for (i = 0; i < path->length - 1; i++) {
243 struct pf_position *pos = path->positions + i;
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);
253 /**********************************************************************
254 Change the destination of the last part to the given location.
255 If a path cannot be found, the destination is set to the start.
256 Return TRUE when the new path is valid.
257 ***********************************************************************/
258 static bool update_last_part(struct goto_map *goto_map,
259 struct tile *ptile)
261 struct pf_path *old_path, *new_path;
262 struct part *p = &goto_map->parts[goto_map->num_parts - 1];
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;
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);
274 if (!new_path) {
275 log_goto_path(" no path found");
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. */
281 if (!goto_warned) {
282 log_error("No path found to reach the start point.");
283 goto_warned = TRUE;
286 if (old_path != NULL) {
287 goto_path_undraw(old_path);
288 pf_path_destroy(old_path);
289 p->path = NULL;
291 if (hover_state == HOVER_PATROL
292 && goto_map->patrol.return_path != NULL) {
293 goto_path_undraw(goto_map->patrol.return_path);
294 pf_path_destroy(goto_map->patrol.return_path);
295 goto_map->patrol.return_path = NULL;
297 return FALSE;
300 reset_last_part(goto_map);
301 return FALSE;
304 log_goto_path(" path found:");
305 pf_path_print(new_path, LOG_GOTO_PATH);
307 p->path = new_path;
308 p->end_tile = ptile;
309 p->end_moves_left = pf_path_last_position(new_path)->moves_left;
310 p->end_fuel_left = pf_path_last_position(new_path)->fuel_left;
312 if (hover_state == HOVER_PATROL) {
313 struct pf_parameter parameter;
314 struct pf_map *pfm;
315 struct pf_path *return_path;
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);
320 pf_map_destroy(pfm);
322 if (return_path == NULL) {
323 log_goto_path(" no return path found");
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. */
329 if (!goto_warned) {
330 log_error("No path found to reach the start point.");
331 goto_warned = TRUE;
334 if (old_path != NULL) {
335 goto_path_undraw(old_path);
336 pf_path_destroy(old_path);
338 pf_path_destroy(new_path);
339 p->path = NULL;
340 if (goto_map->patrol.return_path != NULL) {
341 goto_path_undraw(goto_map->patrol.return_path);
342 pf_path_destroy(goto_map->patrol.return_path);
343 goto_map->patrol.return_path = NULL;
345 return FALSE;
348 p->path = old_path;
349 p->end_tile = pf_path_last_position(old_path)->tile;
350 p->end_moves_left = pf_path_last_position(old_path)->moves_left;
351 p->end_fuel_left = pf_path_last_position(old_path)->fuel_left;
352 pf_path_destroy(new_path);
353 reset_last_part(goto_map);
354 return FALSE;
357 log_goto_path(" returned path found:");
358 pf_path_print(return_path, LOG_GOTO_PATH);
360 if (goto_map->patrol.return_path != NULL) {
361 /* We cannot re-use old path because:
362 * 1- the start tile isn't the same.
363 * 2- the turn number neither (impossible to do in backward mode). */
364 goto_path_undraw(goto_map->patrol.return_path);
365 pf_path_destroy(goto_map->patrol.return_path);
367 goto_path_redraw(return_path, NULL);
368 goto_map->patrol.return_path = return_path;
371 goto_path_redraw(new_path, old_path);
372 pf_path_destroy(old_path);
374 log_goto_path("To (%d,%d) part %d: total_MC: %d",
375 TILE_XY(ptile), goto_map->num_parts,
376 pf_path_last_position(hover_state == HOVER_PATROL
377 ? goto_map->patrol.return_path
378 : new_path)->total_MC);
380 return TRUE;
383 /**********************************************************************
384 Change the drawn path to a size of 0 steps by setting it to the
385 start position.
386 ***********************************************************************/
387 static void reset_last_part(struct goto_map *goto_map)
389 struct part *p = &goto_map->parts[goto_map->num_parts - 1];
391 if (NULL != p->path) {
392 /* Otherwise no need to update */
393 update_last_part(goto_map, p->start_tile);
397 /****************************************************************************
398 Fill pathfinding parameter for adding a new part.
399 ****************************************************************************/
400 static void fill_parameter_part(struct pf_parameter *param,
401 const struct goto_map *goto_map,
402 const struct part *p)
404 *param = goto_map->template;
406 if (p->start_tile == p->end_tile) {
407 /* Copy is enough, we didn't move last part. */
408 fc_assert(p->path->length == 1);
409 return;
412 param->start_tile = p->end_tile;
413 param->moves_left_initially = p->end_moves_left;
414 param->fuel_left_initially = p->end_fuel_left;
415 if (can_exist_at_tile(&(wld.map), param->utype, param->start_tile)) {
416 param->transported_by_initially = NULL;
417 } else {
418 const struct unit *transporter =
419 transporter_for_unit_at(goto_map_unit(goto_map), param->start_tile);
421 param->transported_by_initially = (transporter != NULL
422 ? unit_type_get(transporter) : NULL);
426 /**********************************************************************
427 Add a part. Depending on the num of already existing parts the start
428 of the new part is either the unit position (for the first part) or
429 the destination of the last part (not the first part).
430 ***********************************************************************/
431 static void add_part(struct goto_map *goto_map)
433 struct part *p;
434 struct pf_parameter parameter;
435 struct unit *punit = goto_map_unit(goto_map);
437 goto_map->num_parts++;
438 goto_map->parts =
439 fc_realloc(goto_map->parts,
440 goto_map->num_parts * sizeof(*goto_map->parts));
441 p = &goto_map->parts[goto_map->num_parts - 1];
443 if (goto_map->num_parts == 1) {
444 /* first part */
445 p->start_tile = unit_tile(punit);
446 parameter = goto_map->template;
447 } else {
448 struct part *prev = &goto_map->parts[goto_map->num_parts - 2];
450 p->start_tile = prev->end_tile;
451 fill_parameter_part(&parameter, goto_map, prev);
453 p->path = NULL;
454 p->end_tile = p->start_tile;
455 parameter.start_tile = p->start_tile;
456 p->map = pf_map_new(&parameter);
459 /**********************************************************************
460 Remove the last part, erasing the corresponding path segment.
461 ***********************************************************************/
462 static void remove_last_part(struct goto_map *goto_map)
464 struct part *p = &goto_map->parts[goto_map->num_parts - 1];
466 fc_assert_ret(goto_map->num_parts >= 1);
468 reset_last_part(goto_map);
469 if (p->path) {
470 /* We do not always have a path */
471 pf_path_destroy(p->path);
473 pf_map_destroy(p->map);
474 goto_map->num_parts--;
477 /**********************************************************************
478 Inserts a waypoint at the end of the current goto line.
479 ***********************************************************************/
480 bool goto_add_waypoint(void)
482 bool duplicate_of_last = TRUE;
484 fc_assert_ret_val(goto_is_active(), FALSE);
485 if (NULL == goto_destination) {
486 /* Not a valid position. */
487 return FALSE;
490 goto_map_list_iterate(goto_maps, goto_map) {
491 const struct part *last_part = &goto_map->parts[goto_map->num_parts - 1];
493 if (last_part->path == NULL) {
494 /* The current part has zero length. */
495 return FALSE;
497 if (last_part->start_tile != last_part->end_tile) {
498 duplicate_of_last = FALSE;
500 } goto_map_list_iterate_end;
501 if (duplicate_of_last) {
502 return FALSE;
505 goto_map_list_iterate(goto_maps, goto_map) {
506 add_part(goto_map);
507 } goto_map_list_iterate_end;
509 refresh_tile_mapcanvas(goto_destination, FALSE, FALSE);
510 return TRUE;
513 /**********************************************************************
514 Returns whether there were any waypoint popped (we don't remove the
515 initial position)
516 ***********************************************************************/
517 bool goto_pop_waypoint(void)
519 bool popped = FALSE;
521 fc_assert_ret_val(goto_is_active(), FALSE);
522 goto_map_list_iterate(goto_maps, goto_map) {
523 struct part *p = &goto_map->parts[goto_map->num_parts - 1];
524 struct tile *end_tile = p->end_tile;
526 if (goto_map->num_parts == 1) {
527 /* we don't have any waypoint but the start pos. */
528 continue;
530 popped = TRUE;
532 remove_last_part(goto_map);
535 * Set the end position of the previous part (now the last) to the
536 * end position of the last part (now gone). I.e. redraw a line to
537 * the mouse position.
539 update_last_part(goto_map, end_tile);
540 } goto_map_list_iterate_end;
541 return popped;
544 /**********************************************************************
545 PF callback to get the path with the minimal number of steps (out of
546 all shortest paths).
547 ***********************************************************************/
548 static int get_EC(const struct tile *ptile, enum known_type known,
549 const struct pf_parameter *param)
551 return 1;
554 /**********************************************************************
555 PF callback to prohibit going into the unknown. Also makes sure we
556 don't plan our route through enemy city/tile.
557 ***********************************************************************/
558 static enum tile_behavior get_TB_aggr(const struct tile *ptile,
559 enum known_type known,
560 const struct pf_parameter *param)
562 if (known == TILE_UNKNOWN) {
563 if (!gui_options.goto_into_unknown) {
564 return TB_IGNORE;
566 } else if (is_non_allied_unit_tile(ptile, param->owner)
567 || is_non_allied_city_tile(ptile, param->owner)) {
568 /* Can attack but can't count on going through */
569 return TB_DONT_LEAVE;
571 return TB_NORMAL;
574 /**********************************************************************
575 PF callback for caravans. Caravans doesn't go into the unknown and
576 don't attack enemy units but enter enemy cities.
577 ***********************************************************************/
578 static enum tile_behavior get_TB_caravan(const struct tile *ptile,
579 enum known_type known,
580 const struct pf_parameter *param)
582 if (known == TILE_UNKNOWN) {
583 if (!gui_options.goto_into_unknown) {
584 return TB_IGNORE;
586 } else if (is_non_allied_city_tile(ptile, param->owner)) {
587 /* Units that can establish a trade route, enter a market place or
588 * establish an embassy can travel to, but not through, enemy cities.
589 * FIXME: ACTION_HELP_WONDER units cannot. */
590 return TB_DONT_LEAVE;
591 } else if (is_non_allied_unit_tile(ptile, param->owner)) {
592 /* Note this must be below the city check. */
593 return TB_IGNORE;
596 /* Includes empty, allied, or allied-city tiles. */
597 return TB_NORMAL;
600 /****************************************************************************
601 Return the number of MP needed to do the connect activity at this
602 position. A negative number means it's impossible.
603 ****************************************************************************/
604 static int get_activity_time(const struct tile *ptile,
605 const struct player *pplayer)
607 struct terrain *pterrain = tile_terrain(ptile);
608 int activity_mc = 0;
610 fc_assert_ret_val(hover_state == HOVER_CONNECT, -1);
612 switch (connect_activity) {
613 case ACTIVITY_IRRIGATE:
614 if (pterrain->irrigation_time == 0) {
615 return -1;
617 extra_type_iterate(pextra) {
618 if (BV_ISSET(connect_tgt->conflicts, extra_index(pextra))
619 && tile_has_extra(ptile, pextra)) {
620 /* Don't replace old extras. */
621 return -1;
623 } extra_type_iterate_end;
625 if (tile_has_extra(ptile, connect_tgt)) {
626 break;
629 activity_mc = pterrain->irrigation_time;
630 break;
631 case ACTIVITY_GEN_ROAD:
632 fc_assert(is_extra_caused_by(connect_tgt, EC_ROAD));
634 if (!tile_has_extra(ptile, connect_tgt)) {
635 struct tile *vtile;
636 int single_mc;
638 vtile = tile_virtual_new(ptile);
639 single_mc = check_recursive_road_connect(vtile, connect_tgt, NULL, pplayer, 0);
640 tile_virtual_destroy(vtile);
642 if (single_mc < 0) {
643 return -1;
646 activity_mc += single_mc;
648 break;
649 default:
650 log_error("Invalid connect activity: %d.", connect_activity);
653 return activity_mc;
656 /****************************************************************************
657 When building a road or a railroad, we don't want to go next to
658 nonallied cities
659 ****************************************************************************/
660 static bool is_non_allied_city_adjacent(const struct player *pplayer,
661 const struct tile *ptile)
663 adjc_iterate(&(wld.map), ptile, tile1) {
664 if (is_non_allied_city_tile(tile1, pplayer)) {
665 return TRUE;
667 } adjc_iterate_end;
669 return FALSE;
672 /****************************************************************************
673 PF jumbo callback for the cost of a connect by road.
674 In road-connect mode we are concerned with
675 (1) the number of steps of the resulting path
676 (2) (the tie-breaker) time to build the path (travel plus activity time).
677 In rail-connect the priorities are reversed.
679 param->data should contain the result of get_activity_rate(punit).
680 ****************************************************************************/
681 static int get_connect_road(const struct tile *src_tile, enum direction8 dir,
682 const struct tile *dest_tile,
683 int src_cost, int src_extra,
684 int *dest_cost, int *dest_extra,
685 const struct pf_parameter *param)
687 int activity_time, move_cost, moves_left;
688 int total_cost, total_extra;
689 struct road_type *proad;
691 if (tile_get_known(dest_tile, param->owner) == TILE_UNKNOWN) {
692 return -1;
695 activity_time = get_activity_time(dest_tile, param->owner);
696 if (activity_time < 0) {
697 return -1;
700 move_cost = param->get_MC(src_tile, PF_MS_NATIVE, dest_tile, PF_MS_NATIVE,
701 param);
702 if (move_cost == PF_IMPOSSIBLE_MC) {
703 return -1;
706 if (is_non_allied_city_adjacent(param->owner, dest_tile)) {
707 /* We don't want to build roads to enemies plus get ZoC problems */
708 return -1;
711 fc_assert(connect_activity == ACTIVITY_GEN_ROAD);
713 proad = extra_road_get(connect_tgt);
715 if (proad == NULL) {
716 /* No suitable road type available */
717 return -1;
720 /* Ok, the move is possible. What are the costs? */
722 /* Extra cost here is the final length of the road */
723 total_extra = src_extra + 1;
725 /* Special cases: get_MC function doesn't know that we would have built
726 * a road (railroad) on src tile by that time.
727 * We assume that settler building the road can also travel it. */
728 if (tile_has_road(dest_tile, proad)) {
729 move_cost = proad->move_cost;
732 move_cost = MIN(move_cost, param->move_rate);
733 total_cost = src_cost;
734 moves_left = param->move_rate - (src_cost % param->move_rate);
735 if (moves_left < move_cost) {
736 total_cost += moves_left;
737 } else {
738 total_cost += move_cost;
741 /* Now need to include the activity cost. If we have moves left, they
742 * will count as a full turn towards the activity time */
743 moves_left = param->move_rate - (total_cost % param->move_rate);
744 if (activity_time > 0) {
745 int speed = FC_PTR_TO_INT(param->data);
747 activity_time = ((activity_time * ACTIVITY_FACTOR)
748 + (speed - 1)) / speed;
749 activity_time--;
750 total_cost += moves_left;
752 total_cost += activity_time * param->move_rate;
754 /* Now we determine if we have found a better path. When building
755 * road type with positive move_cost, we care most about the length
756 * of the result. When building road type with move_cost 0, we
757 * care most about construction time. */
759 /* *dest_cost == -1 means we haven't reached dest until now */
761 if (*dest_cost != -1) {
762 if (proad->move_cost > 0) {
763 if (total_extra > *dest_extra
764 || (total_extra == *dest_extra && total_cost >= *dest_cost)) {
765 /* No, this path is worse than what we already have */
766 return -1;
768 } else {
769 if (total_cost > *dest_cost
770 || (total_cost == *dest_cost && total_extra >= *dest_extra)) {
771 return -1;
776 /* Ok, we found a better path! */
777 *dest_cost = total_cost;
778 *dest_extra = total_extra;
780 return (proad->move_cost > 0 ?
781 total_extra * PF_TURN_FACTOR + total_cost :
782 total_cost * PF_TURN_FACTOR + total_extra);
785 /****************************************************************************
786 PF jumbo callback for the cost of a connect by irrigation.
787 Here we are only interested in how long it will take to irrigate the path.
789 param->data should contain the result of get_activity_rate(punit) / 10.
790 ****************************************************************************/
791 static int get_connect_irrig(const struct tile *src_tile,
792 enum direction8 dir,
793 const struct tile *dest_tile,
794 int src_cost, int src_extra,
795 int *dest_cost, int *dest_extra,
796 const struct pf_parameter *param)
798 int activity_time, move_cost, moves_left, total_cost;
800 if (tile_get_known(dest_tile, param->owner) == TILE_UNKNOWN) {
801 return -1;
804 activity_time = get_activity_time(dest_tile, param->owner);
805 if (activity_time < 0) {
806 return -1;
809 if (!is_cardinal_dir(dir)) {
810 return -1;
813 move_cost = param->get_MC(src_tile, PF_MS_NATIVE, dest_tile, PF_MS_NATIVE,
814 param);
815 if (move_cost == PF_IMPOSSIBLE_MC) {
816 return -1;
819 if (is_non_allied_city_adjacent(param->owner, dest_tile)) {
820 /* We don't want to build irrigation for enemies plus get ZoC problems */
821 return -1;
824 /* Ok, the move is possible. What are the costs? */
826 move_cost = MIN(move_cost, param->move_rate);
827 total_cost = src_cost;
828 moves_left = param->move_rate - (src_cost % param->move_rate);
829 if (moves_left < move_cost) {
830 total_cost += moves_left;
831 } else {
832 total_cost += move_cost;
835 /* Now need to include the activity cost. If we have moves left, they
836 * will count as a full turn towards the activity time */
837 moves_left = param->move_rate - (total_cost % param->move_rate);
838 if (activity_time > 0) {
839 int speed = FC_PTR_TO_INT(param->data);
841 activity_time = ((activity_time * ACTIVITY_FACTOR)
842 + (speed - 1)) / speed;
843 activity_time--;
844 total_cost += moves_left;
846 total_cost += activity_time * param->move_rate;
848 /* *dest_cost == -1 means we haven't reached dest until now */
849 if (*dest_cost != -1 && total_cost > *dest_cost) {
850 return -1;
853 /* Ok, we found a better path! */
854 *dest_cost = total_cost;
855 *dest_extra = 0;
857 return total_cost;
860 /**********************************************************************
861 PF callback to prohibit going into the unknown (conditionally). Also
862 makes sure we don't plan to attack anyone.
863 ***********************************************************************/
864 static enum tile_behavior
865 no_fights_or_unknown_goto(const struct tile *ptile,
866 enum known_type known,
867 const struct pf_parameter *p)
869 if (known == TILE_UNKNOWN && gui_options.goto_into_unknown) {
870 /* Special case allowing goto into the unknown. */
871 return TB_NORMAL;
874 return no_fights_or_unknown(ptile, known, p);
877 /****************************************************************************
878 Fill the PF parameter with the correct client-goto values.
879 See also goto_fill_parameter_full().
880 ****************************************************************************/
881 static void goto_fill_parameter_base(struct pf_parameter *parameter,
882 const struct unit *punit)
884 pft_fill_unit_parameter(parameter, punit);
886 fc_assert(parameter->get_EC == NULL);
887 fc_assert(parameter->get_TB == NULL);
888 fc_assert(parameter->get_MC != NULL);
889 fc_assert(parameter->start_tile == unit_tile(punit));
890 fc_assert(parameter->omniscience == FALSE);
892 parameter->get_EC = get_EC;
893 if (is_attack_unit(punit)
894 || utype_acts_hostile(unit_type_get(punit))) {
895 parameter->get_TB = get_TB_aggr;
896 } else if (utype_may_act_at_all(unit_type_get(punit))
897 && !utype_acts_hostile(unit_type_get(punit))) {
898 parameter->get_TB = get_TB_caravan;
899 } else {
900 parameter->get_TB = no_fights_or_unknown_goto;
904 /****************************************************************************
905 Fill the PF parameter with the correct client-goto values.
906 The storage behind "connect_speed" must remain valid for the lifetime
907 of the pf_map.
909 Note that you must call this function only if the 'hover_state' is set,
910 and we are in goto mode (usually, this function is only called from
911 enter_goto_state()).
913 See also goto_fill_parameter_base().
914 ****************************************************************************/
915 static void goto_fill_parameter_full(struct goto_map *goto_map,
916 const struct unit *punit)
918 struct pf_parameter *parameter = &goto_map->template;
920 goto_fill_parameter_base(parameter, punit);
922 fc_assert_ret(goto_is_active());
924 switch (hover_state) {
925 case HOVER_CONNECT:
927 int activity_initial;
928 int speed;
930 if (connect_activity == ACTIVITY_IRRIGATE) {
931 parameter->get_costs = get_connect_irrig;
932 } else {
933 parameter->get_costs = get_connect_road;
935 parameter->get_moves_left_req = NULL;
937 speed = get_activity_rate(punit);
938 parameter->data = FC_INT_TO_PTR(speed);
940 /* Take into account the activity time at the origin */
941 activity_initial = get_activity_time(unit_tile(punit),
942 unit_owner(punit));
944 if (activity_initial > 0) {
945 /* First action is activity */
946 parameter->moves_left_initially = parameter->move_rate;
947 /* Number of turns, rounding up */
948 goto_map->connect.initial_turns =
949 ((activity_initial * ACTIVITY_FACTOR + (speed - 1)) / speed);
950 if (punit->moves_left == 0) {
951 goto_map->connect.initial_turns++;
953 } else {
954 goto_map->connect.initial_turns = 0;
957 break;
958 case HOVER_GOTO:
959 case HOVER_PATROL:
960 if (goto_last_action == ACTION_NUKE) {
961 /* We only want targets reachable immediatly... */
962 parameter->move_rate = 0;
963 /* ...then we don't need to deal with dangers or refuel points. */
964 parameter->is_pos_dangerous = NULL;
965 parameter->get_moves_left_req = NULL;
966 } else {
967 goto_map->patrol.return_path = NULL;
969 break;
970 case HOVER_NONE:
971 case HOVER_PARADROP:
972 case HOVER_ACT_SEL_TGT:
973 fc_assert_msg(hover_state != HOVER_NONE, "Goto with HOVER_NONE?");
974 fc_assert_msg(hover_state != HOVER_PARADROP,
975 "Goto with HOVER_PARADROP?");
976 fc_assert_msg(hover_state != HOVER_ACT_SEL_TGT,
977 "Goto with HOVER_ACT_SEL_TGT?");
978 break;
982 /**********************************************************************
983 Enter the goto state: activate, prepare PF-template and add the
984 initial part.
985 ***********************************************************************/
986 void enter_goto_state(struct unit_list *punits)
988 fc_assert_ret(!goto_is_active());
990 /* Can't have selection rectangle and goto going on at the same time. */
991 cancel_selection_rectangle();
993 unit_list_iterate(punits, punit) {
994 struct goto_map *goto_map = goto_map_new(punit);
996 goto_map_list_append(goto_maps, goto_map);
998 goto_fill_parameter_full(goto_map, punit);
999 add_part(goto_map);
1000 } unit_list_iterate_end;
1001 goto_warned = FALSE;
1004 /**********************************************************************
1005 Tidy up and deactivate goto state.
1006 ***********************************************************************/
1007 void exit_goto_state(void)
1009 if (!goto_is_active()) {
1010 return;
1013 goto_map_list_iterate(goto_maps, goto_map) {
1014 goto_map_free(goto_map);
1015 } goto_map_list_iterate_end;
1016 goto_map_list_clear(goto_maps);
1018 goto_destination = NULL;
1019 goto_warned = FALSE;
1022 /**********************************************************************
1023 Called from control_unit_killed() in client/control.c
1024 ***********************************************************************/
1025 void goto_unit_killed(struct unit *punit)
1027 if (!goto_is_active()) {
1028 return;
1031 goto_map_unit_iterate(goto_maps, goto_map, ptest) {
1032 if (ptest == punit) {
1033 goto_map_free(goto_map);
1034 /* Still safe using goto_map pointer, as it is not used for
1035 * dereferencing, only as value. */
1036 goto_map_list_remove(goto_maps, goto_map);
1037 /* stop now, links are gone! */
1038 break;
1040 } goto_map_unit_iterate_end;
1043 /**********************************************************************
1044 Is goto state active?
1045 ***********************************************************************/
1046 bool goto_is_active(void)
1048 return (NULL != goto_maps && 0 != goto_map_list_size(goto_maps));
1051 /**************************************************************************
1052 Return the path length (in turns).
1053 WARNING: not useful for determining paths of scattered groups.
1054 ***************************************************************************/
1055 bool goto_get_turns(int *min, int *max)
1057 fc_assert_ret_val(min != NULL, FALSE);
1058 fc_assert_ret_val(max != NULL, FALSE);
1060 *min = FC_INFINITY;
1061 *max = -1;
1063 if (!goto_is_active()) {
1064 return FALSE;
1066 if (NULL == goto_destination) {
1067 /* Not a valid position. */
1068 return FALSE;
1071 if (hover_state == HOVER_CONNECT) {
1072 /* In connect mode, we want to know the turn number the activity will
1073 * be finished. */
1074 int activity_time = get_activity_time(goto_destination, client_player());
1076 goto_map_list_iterate(goto_maps, goto_map) {
1077 bool moved = FALSE;
1078 int turns = goto_map->connect.initial_turns;
1079 int i;
1081 for (i = 0; i < goto_map->num_parts; i++) {
1082 const struct pf_path *path = goto_map->parts[i].path;
1084 turns += pf_path_last_position(goto_map->parts[i].path)->turn;
1085 if (!moved && path->length > 1) {
1086 moved = TRUE;
1090 if (moved && activity_time > 0) {
1091 turns++;
1094 if (turns < *min) {
1095 *min = turns;
1097 if (turns > *max) {
1098 *max = turns;
1100 } goto_map_list_iterate_end;
1101 } else {
1102 /* In other modes, we want to know the turn number to reach the tile. */
1103 goto_map_list_iterate(goto_maps, goto_map) {
1104 int turns = 0;
1105 int i;
1107 for (i = 0; i < goto_map->num_parts; i++) {
1108 turns += pf_path_last_position(goto_map->parts[i].path)->turn;
1110 if (hover_state == HOVER_PATROL
1111 && goto_map->patrol.return_path != NULL) {
1112 turns += pf_path_last_position(goto_map->patrol.return_path)->turn;
1115 if (turns < *min) {
1116 *min = turns;
1118 if (turns > *max) {
1119 *max = turns;
1121 } goto_map_list_iterate_end;
1124 return TRUE;
1127 /****************************************************************************
1128 Returns the state of 'ptile': turn number to print, and whether 'ptile'
1129 is a waypoint.
1130 ****************************************************************************/
1131 bool goto_tile_state(const struct tile *ptile, enum goto_tile_state *state,
1132 int *turns, bool *waypoint)
1134 fc_assert_ret_val(ptile != NULL, FALSE);
1135 fc_assert_ret_val(turns != NULL, FALSE);
1136 fc_assert_ret_val(waypoint != NULL, FALSE);
1138 if (!goto_is_active()) {
1139 return FALSE;
1142 *state = -1;
1143 *turns = -1;
1144 *waypoint = FALSE;
1146 if (hover_state == HOVER_CONNECT) {
1147 /* In connect mode, we want to know the turn number the activity will
1148 * be finished. */
1149 int activity_time;
1151 if (tile_get_known(ptile, client_player()) == TILE_UNKNOWN) {
1152 return FALSE; /* We never connect on unknown tiles. */
1155 activity_time = get_activity_time(ptile, client_player());
1157 goto_map_list_iterate(goto_maps, goto_map) {
1158 const struct pf_path *path;
1159 const struct pf_position *pos = NULL; /* Keep compiler happy! */
1160 int map_turns = goto_map->connect.initial_turns;
1161 int turns_for_map = -2;
1162 bool moved = FALSE;
1163 int i, j;
1165 for (i = 0; i < goto_map->num_parts; i++) {
1166 if (i > 0 && goto_map->parts[i].start_tile == ptile) {
1167 *waypoint = TRUE;
1170 path = goto_map->parts[i].path;
1171 if (path == NULL) {
1172 continue;
1175 for (j = 0; j < path->length; j++) {
1176 pos = path->positions + j;
1177 if (!moved && j > 0) {
1178 moved = TRUE;
1180 if (pos->tile != ptile) {
1181 continue;
1183 if (activity_time > 0) {
1184 if (map_turns + pos->turn + moved > turns_for_map) {
1185 turns_for_map = map_turns + pos->turn + moved;
1187 } else if (pos->moves_left == 0) {
1188 if (map_turns + pos->turn > turns_for_map) {
1189 turns_for_map = map_turns + pos->turn + moved;
1193 map_turns += pos->turn;
1196 if (ptile == goto_destination) {
1197 fc_assert_ret_val(pos != NULL, FALSE);
1198 if (moved && activity_time > 0) {
1199 map_turns++;
1201 if (map_turns > *turns) {
1202 *state = (activity_time > 0 || pos->moves_left == 0
1203 ? GTS_EXHAUSTED_MP : GTS_MP_LEFT);
1204 *turns = map_turns;
1205 } else if (map_turns == *turns
1206 && *state == GTS_MP_LEFT
1207 && (activity_time > 0 || pos->moves_left == 0)) {
1208 *state = GTS_EXHAUSTED_MP;
1210 } else {
1211 if (activity_time > 0) {
1212 if (turns_for_map > *turns) {
1213 *state = GTS_TURN_STEP;
1214 *turns = turns_for_map;
1216 } else {
1217 if (turns_for_map + 1 > *turns) {
1218 *state = GTS_TURN_STEP;
1219 *turns = turns_for_map + 1;
1223 } goto_map_list_iterate_end;
1224 } else {
1225 /* In other modes, we want to know the turn number to reach the tile. */
1226 goto_map_list_iterate(goto_maps, goto_map) {
1227 const struct tile *destination;
1228 const struct pf_path *path;
1229 const struct pf_position *pos = NULL; /* Keep compiler happy! */
1230 int map_turns = 0;
1231 int turns_for_map = -2;
1232 int i, j;
1234 for (i = 0; i < goto_map->num_parts; i++) {
1235 if (i > 0 && goto_map->parts[i].start_tile == ptile) {
1236 *waypoint = TRUE;
1239 path = goto_map->parts[i].path;
1240 if (path == NULL) {
1241 continue;
1244 for (j = 0; j < path->length; j++) {
1245 pos = path->positions + j;
1246 if (pos->tile == ptile
1247 /* End turn case. */
1248 && (pos->moves_left == 0
1249 /* Waiting case. */
1250 || (j < path->length - 1 && (pos + 1)->tile == ptile))
1251 && map_turns + pos->turn > turns_for_map) {
1252 turns_for_map = map_turns + pos->turn;
1255 map_turns += pos->turn;
1258 if (hover_state == HOVER_PATROL
1259 && goto_map->patrol.return_path != NULL) {
1260 path = goto_map->patrol.return_path;
1261 for (j = 0; j < path->length; j++) {
1262 pos = path->positions + j;
1263 if (pos->tile == ptile
1264 /* End turn case. */
1265 && (pos->moves_left == 0
1266 /* Waiting case. */
1267 || (j < path->length - 1 && (pos + 1)->tile == ptile))
1268 && map_turns + pos->turn > turns_for_map) {
1269 turns_for_map = map_turns + pos->turn;
1272 map_turns += pos->turn;
1273 destination = pos->tile;
1274 } else {
1275 destination = goto_destination;
1278 if (ptile == destination) {
1279 fc_assert_ret_val(pos != NULL, FALSE);
1280 if (map_turns > *turns) {
1281 *state = (pos->moves_left == 0 ? GTS_EXHAUSTED_MP : GTS_MP_LEFT);
1282 *turns = map_turns;
1283 } else if (map_turns == *turns
1284 && *state == GTS_MP_LEFT
1285 && pos->moves_left == 0) {
1286 *state = GTS_EXHAUSTED_MP;
1288 } else {
1289 if (turns_for_map + 1 > *turns) {
1290 *state = GTS_TURN_STEP;
1291 *turns = turns_for_map + 1;
1294 } goto_map_list_iterate_end;
1297 return (*turns != -1 || *waypoint);
1300 /**********************************************************************
1301 Puts a line to dest_tile on the map according to the current
1302 goto_map.
1303 If there is no route to the dest then don't draw anything.
1304 ***********************************************************************/
1305 bool is_valid_goto_draw_line(struct tile *dest_tile)
1307 fc_assert_ret_val(goto_is_active(), FALSE);
1308 if (NULL == dest_tile) {
1309 return FALSE;
1312 /* assume valid destination */
1313 goto_destination = dest_tile;
1315 goto_map_list_iterate(goto_maps, goto_map) {
1316 if (!update_last_part(goto_map, dest_tile)) {
1317 goto_destination = NULL;
1319 } goto_map_list_iterate_end;
1321 /* Update goto data in info label. */
1322 update_unit_info_label(get_units_in_focus());
1323 return (NULL != goto_destination);
1326 /****************************************************************************
1327 Send a packet to the server to request that the current orders be
1328 cleared.
1329 ****************************************************************************/
1330 void request_orders_cleared(struct unit *punit)
1332 struct packet_unit_orders p;
1334 if (!can_client_issue_orders()) {
1335 return;
1338 /* Clear the orders by sending an empty orders path. */
1339 log_goto_packet("Clearing orders for unit %d.", punit->id);
1340 p.unit_id = punit->id;
1341 p.src_tile = tile_index(unit_tile(punit));
1342 p.repeat = p.vigilant = FALSE;
1343 p.length = 0;
1344 p.dest_tile = tile_index(unit_tile(punit));
1345 send_packet_unit_orders(&client.conn, &p);
1348 /**************************************************************************
1349 Send a path as a goto or patrol route to the server.
1350 **************************************************************************/
1351 static void send_path_orders(struct unit *punit, struct pf_path *path,
1352 bool repeat, bool vigilant,
1353 enum unit_orders orders,
1354 struct unit_order *final_order)
1356 struct packet_unit_orders p;
1357 int i;
1358 struct tile *old_tile;
1360 fc_assert_ret(path != NULL);
1361 fc_assert_ret_msg(unit_tile(punit) == path->positions[0].tile,
1362 "Unit %d has moved without goto cancelation.",
1363 punit->id);
1365 if (path->length == 1 && final_order == NULL) {
1366 return; /* No path at all, no need to spam the server. */
1369 memset(&p, 0, sizeof(p));
1370 p.unit_id = punit->id;
1371 p.src_tile = tile_index(unit_tile(punit));
1372 p.repeat = repeat;
1373 p.vigilant = vigilant;
1375 log_goto_packet("Orders for unit %d:", punit->id);
1377 /* We skip the start position. */
1378 p.length = path->length - 1;
1379 fc_assert(p.length < MAX_LEN_ROUTE);
1380 old_tile = path->positions[0].tile;
1382 log_goto_packet(" Repeat: %d. Vigilant: %d. Length: %d",
1383 p.repeat, p.vigilant, p.length);
1385 /* If the path has n positions it takes n-1 steps. */
1386 for (i = 0; i < path->length - 1; i++) {
1387 struct tile *new_tile = path->positions[i + 1].tile;
1389 if (same_pos(new_tile, old_tile)) {
1390 p.orders[i] = ORDER_FULL_MP;
1391 p.dir[i] = DIR8_ORIGIN;
1392 p.activity[i] = ACTIVITY_LAST;
1393 p.target[i] = EXTRA_NONE;
1394 p.action[i] = ACTION_NONE;
1395 log_goto_packet(" packet[%d] = wait: %d,%d", i, TILE_XY(old_tile));
1396 } else {
1397 p.orders[i] = orders;
1398 p.dir[i] = get_direction_for_step(&(wld.map), old_tile, new_tile);
1399 p.activity[i] = ACTIVITY_LAST;
1400 p.target[i] = EXTRA_NONE;
1401 p.action[i] = ACTION_NONE;
1402 log_goto_packet(" packet[%d] = move %s: %d,%d => %d,%d",
1403 i, dir_get_name(p.dir[i]),
1404 TILE_XY(old_tile), TILE_XY(new_tile));
1406 old_tile = new_tile;
1409 if (p.orders[i - 1] == ORDER_MOVE
1410 && (is_non_allied_city_tile(old_tile, client_player()) != NULL
1411 || is_non_allied_unit_tile(old_tile, client_player()) != NULL)) {
1412 /* Won't be able to perform a regular move to the target tile... */
1413 if (!final_order) {
1414 /* ...and no final order exists. Choose what to do when the unit gets
1415 * there. */
1416 p.orders[i - 1] = ORDER_ACTION_MOVE;
1417 } else {
1418 /* ...and a final order exist. Can't assume an action move. Did the
1419 * caller hope that the situation would change before the unit got
1420 * there? */
1422 /* It's currently illegal to walk into tiles with non allied units or
1423 * cities. Some actions causes the actor to enter the target tile but
1424 * that is a part of the action it self, not a regular pre action
1425 * move. */
1426 log_verbose("unit or city blocks the path of your %s",
1427 unit_rule_name(punit));
1431 if (final_order) {
1432 /* Append the final order after moving to the target tile. */
1433 p.orders[i] = final_order->order;
1434 p.dir[i] = final_order->dir;
1435 p.activity[i] = (final_order->order == ORDER_ACTIVITY)
1436 ? final_order->activity : ACTIVITY_LAST;
1437 p.target[i] = final_order->target;
1438 p.action[i] = final_order->action;
1439 p.length++;
1442 p.dest_tile = tile_index(old_tile);
1444 send_packet_unit_orders(&client.conn, &p);
1447 /**************************************************************************
1448 Send an arbitrary goto path for the unit to the server.
1449 **************************************************************************/
1450 void send_goto_path(struct unit *punit, struct pf_path *path,
1451 struct unit_order *final_order)
1453 send_path_orders(punit, path, FALSE, FALSE, ORDER_MOVE, final_order);
1456 /****************************************************************************
1457 Send orders for the unit to move it to the arbitrary tile. Returns
1458 FALSE if no path is found.
1459 ****************************************************************************/
1460 bool send_goto_tile(struct unit *punit, struct tile *ptile)
1462 struct pf_parameter parameter;
1463 struct pf_map *pfm;
1464 struct pf_path *path;
1466 goto_fill_parameter_base(&parameter, punit);
1467 pfm = pf_map_new(&parameter);
1468 path = pf_map_path(pfm, ptile);
1469 pf_map_destroy(pfm);
1471 if (path) {
1472 send_goto_path(punit, path, NULL);
1473 pf_path_destroy(path);
1474 return TRUE;
1475 } else {
1476 return FALSE;
1480 /****************************************************************************
1481 Send orders for the unit to move it to the arbitrary tile and attack
1482 everything it approaches. Returns FALSE if no path is found.
1483 ****************************************************************************/
1484 bool send_attack_tile(struct unit *punit, struct tile *ptile)
1486 struct pf_parameter parameter;
1487 struct pf_map *pfm;
1488 struct pf_path *path;
1490 goto_fill_parameter_base(&parameter, punit);
1491 parameter.move_rate = 0;
1492 parameter.is_pos_dangerous = NULL;
1493 parameter.get_moves_left_req = NULL;
1494 pfm = pf_map_new(&parameter);
1495 path = pf_map_path(pfm, ptile);
1496 pf_map_destroy(pfm);
1498 if (path) {
1499 send_path_orders(punit, path, false, false, ORDER_ACTION_MOVE, NULL);
1500 pf_path_destroy(path);
1501 return TRUE;
1503 return FALSE;
1506 /**************************************************************************
1507 Send the current patrol route (i.e., the one generated via HOVER_STATE)
1508 to the server.
1509 **************************************************************************/
1510 void send_patrol_route(void)
1512 fc_assert_ret(goto_is_active());
1513 goto_map_unit_iterate(goto_maps, goto_map, punit) {
1514 int i;
1515 struct pf_path *path = NULL;
1516 struct part *last_part = &goto_map->parts[goto_map->num_parts - 1];
1518 if (NULL == last_part->path) {
1519 /* Cannot move there */
1520 continue;
1523 for (i = 0; i < goto_map->num_parts; i++) {
1524 path = pf_path_concat(path, goto_map->parts[i].path);
1526 path = pf_path_concat(path, goto_map->patrol.return_path);
1528 send_path_orders(punit, path, TRUE, TRUE, ORDER_MOVE, NULL);
1530 pf_path_destroy(path);
1531 } goto_map_unit_iterate_end;
1534 /**************************************************************************
1535 Fill orders to build recursive roads.
1536 **************************************************************************/
1537 static bool order_recursive_roads(struct tile *ptile, struct extra_type *pextra,
1538 struct packet_unit_orders *p, int rec)
1540 if (rec > MAX_EXTRA_TYPES) {
1541 return FALSE;
1544 if (!is_extra_caused_by(pextra, EC_ROAD)) {
1545 return FALSE;
1548 extra_deps_iterate(&(pextra->reqs), pdep) {
1549 if (!tile_has_extra(ptile, pdep)) {
1550 if (!order_recursive_roads(ptile, pdep, p, rec + 1)) {
1551 return FALSE;
1554 } extra_deps_iterate_end;
1556 p->orders[p->length] = ORDER_ACTIVITY;
1557 p->dir[p->length] = DIR8_ORIGIN;
1558 p->activity[p->length] = ACTIVITY_GEN_ROAD;
1559 p->target[p->length] = extra_index(pextra);
1560 p->action[p->length] = ACTION_NONE;
1561 p->length++;
1563 return TRUE;
1566 /**************************************************************************
1567 Send the current connect route (i.e., the one generated via HOVER_STATE)
1568 to the server.
1569 **************************************************************************/
1570 void send_connect_route(enum unit_activity activity,
1571 struct extra_type *tgt)
1573 fc_assert_ret(goto_is_active());
1574 goto_map_unit_iterate(goto_maps, goto_map, punit) {
1575 int i;
1576 struct packet_unit_orders p;
1577 struct tile *old_tile;
1578 struct pf_path *path = NULL;
1579 struct part *last_part = &goto_map->parts[goto_map->num_parts - 1];
1581 if (NULL == last_part->path) {
1582 /* Cannot move there */
1583 continue;
1586 memset(&p, 0, sizeof(p));
1588 for (i = 0; i < goto_map->num_parts; i++) {
1589 path = pf_path_concat(path, goto_map->parts[i].path);
1592 p.unit_id = punit->id;
1593 p.src_tile = tile_index(unit_tile(punit));
1594 p.repeat = FALSE;
1595 p.vigilant = FALSE; /* Should be TRUE? */
1597 p.length = 0;
1598 old_tile = path->positions[0].tile;
1600 for (i = 0; i < path->length; i++) {
1601 switch (activity) {
1602 case ACTIVITY_IRRIGATE:
1603 if (!tile_has_extra(old_tile, tgt)) {
1604 /* Assume the unit can irrigate or we wouldn't be here. */
1605 p.orders[p.length] = ORDER_ACTIVITY;
1606 p.dir[p.length] = DIR8_ORIGIN;
1607 p.activity[p.length] = ACTIVITY_IRRIGATE;
1608 p.target[p.length] = extra_index(tgt);
1609 p.action[p.length] = ACTION_NONE;
1610 p.length++;
1612 break;
1613 case ACTIVITY_GEN_ROAD:
1614 order_recursive_roads(old_tile, tgt, &p, 0);
1615 break;
1616 default:
1617 log_error("Invalid connect activity: %d.", activity);
1618 break;
1621 if (i != path->length - 1) {
1622 struct tile *new_tile = path->positions[i + 1].tile;
1624 fc_assert(!same_pos(new_tile, old_tile));
1626 p.orders[p.length] = ORDER_MOVE;
1627 p.dir[p.length] = get_direction_for_step(&(wld.map),
1628 old_tile, new_tile);
1629 p.activity[p.length] = ACTIVITY_LAST;
1630 p.target[p.length] = EXTRA_NONE;
1631 p.action[p.length] = ACTION_NONE;
1632 p.length++;
1634 old_tile = new_tile;
1638 p.dest_tile = tile_index(old_tile);
1640 send_packet_unit_orders(&client.conn, &p);
1641 } goto_map_unit_iterate_end;
1644 /**************************************************************************
1645 Returns TRUE if the order preferably should be performed from an
1646 adjacent tile.
1648 This function doesn't care if a direction is required or just possible.
1649 Use order_demands_direction() for that.
1650 **************************************************************************/
1651 static bool order_wants_direction(enum unit_orders order, int act_id,
1652 struct tile *tgt_tile)
1654 switch (order) {
1655 case ORDER_MOVE:
1656 case ORDER_ACTION_MOVE:
1657 /* Not only is it legal. It is mandatory. A move is always done in a
1658 * direction. */
1659 return TRUE;
1660 case ORDER_PERFORM_ACTION:
1661 if (!action_id_distance_accepted(act_id, 0)) {
1662 /* Always illegal to do to a target on the actor's own tile. */
1663 return TRUE;
1666 if (!action_id_distance_accepted(act_id, 1)) {
1667 /* Always illegal to perform to a target on a neighbor tile. */
1668 return FALSE;
1671 if (is_non_allied_city_tile(tgt_tile, client_player()) != NULL
1672 || is_non_allied_unit_tile(tgt_tile, client_player()) != NULL) {
1673 /* Won't be able to move to the target tile to perform the action on
1674 * top of it. */
1675 /* TODO: detect situations where it also would be illegal to perform
1676 * the action from the neighbor tile. */
1677 return TRUE;
1680 return FALSE;
1681 default:
1682 return FALSE;
1686 /**************************************************************************
1687 Returns TRUE if it is certain that the order must be performed from an
1688 adjacent tile.
1689 **************************************************************************/
1690 static bool order_demands_direction(enum unit_orders order, int act_id)
1692 switch (order) {
1693 case ORDER_MOVE:
1694 case ORDER_ACTION_MOVE:
1695 /* A move is always done in a direction. */
1696 return TRUE;
1697 case ORDER_PERFORM_ACTION:
1698 if (!action_id_distance_accepted(act_id, 0)) {
1699 /* Always illegal to do to a target on the actor's own tile. */
1700 return TRUE;
1703 return FALSE;
1704 default:
1705 return FALSE;
1709 /**************************************************************************
1710 Send the current goto route (i.e., the one generated via
1711 HOVER_STATE) to the server. The route might involve more than one
1712 part if waypoints were used. FIXME: danger paths are not supported.
1713 **************************************************************************/
1714 void send_goto_route(void)
1716 fc_assert_ret(goto_is_active());
1717 goto_map_unit_iterate(goto_maps, goto_map, punit) {
1718 int i;
1719 struct tile *tgt_tile;
1720 struct pf_path *path = NULL;
1721 struct part *last_part = &goto_map->parts[goto_map->num_parts - 1];
1723 if (NULL == last_part->path) {
1724 /* Cannot move there */
1725 continue;
1728 for (i = 0; i < goto_map->num_parts; i++) {
1729 path = pf_path_concat(path, goto_map->parts[i].path);
1732 clear_unit_orders(punit);
1734 tgt_tile = pf_path_last_position(path)->tile;
1736 /* Make the last move in a plain goto try to pop up the action
1737 * selection dialog rather than moving to the last tile if it contains
1738 * a domestic, allied or team mate city, unit or unit stack. This can,
1739 * in cases where the action requires movement left, save a turn. */
1740 /* TODO: Should this be a client option? */
1741 if (goto_last_order == ORDER_LAST
1742 && ((is_allied_city_tile(tgt_tile, client_player())
1743 || is_allied_unit_tile(tgt_tile, client_player()))
1744 && (can_utype_do_act_if_tgt_diplrel(unit_type_get(punit),
1745 ACTION_ANY,
1746 DRO_FOREIGN,
1747 FALSE)
1748 || can_utype_do_act_if_tgt_diplrel(unit_type_get(punit),
1749 ACTION_ANY,
1750 DS_ALLIANCE,
1751 TRUE)
1752 || can_utype_do_act_if_tgt_diplrel(unit_type_get(punit),
1753 ACTION_ANY,
1754 DS_TEAM,
1755 TRUE)))) {
1756 /* Try to pop up the action selection dialog before moving to the
1757 * target tile. */
1758 goto_last_order = ORDER_ACTION_MOVE;
1761 if (goto_last_order == ORDER_LAST) {
1762 send_goto_path(punit, path, NULL);
1763 } else if (path->length > 1
1764 || !order_demands_direction(goto_last_order,
1765 goto_last_action)) {
1766 struct unit_order order;
1767 int last_order_dir;
1768 struct tile *on_tile;
1770 if (path->length > 1
1771 && ((on_tile = path->positions[path->length - 2].tile))
1772 && order_wants_direction(goto_last_order, goto_last_action,
1773 tgt_tile)
1774 && !same_pos(on_tile, tgt_tile)) {
1775 /* The last order prefers to handle the last direction it self.
1776 * There exists a tile before the target tile to do it from. */
1778 /* Give the last path direction to the final order. */
1779 last_order_dir = get_direction_for_step(&(wld.map), on_tile, tgt_tile);
1781 /* The last path direction is now spent. */
1782 pf_path_backtrack(path, on_tile);
1783 } else {
1784 fc_assert(!order_demands_direction(goto_last_order,
1785 goto_last_action));
1787 /* Target the tile the actor is standing on. */
1788 last_order_dir = DIR8_ORIGIN;
1791 order.order = goto_last_order;
1792 order.dir = DIR8_ORIGIN;
1793 order.dir = last_order_dir;
1794 order.activity = ACTIVITY_LAST;
1795 order.target = goto_last_tgt;
1796 order.action = goto_last_action;
1798 /* ORDER_ACTIVITY would require real activity */
1799 fc_assert(goto_last_order != ORDER_ACTIVITY);
1801 send_goto_path(punit, path, &order);
1803 pf_path_destroy(path);
1804 } goto_map_unit_iterate_end;
1807 /**************************************************************************
1808 Find the path to the nearest (fastest to reach) allied city for the
1809 unit, or NULL if none is reachable.
1810 ***************************************************************************/
1811 struct pf_path *path_to_nearest_allied_city(struct unit *punit)
1813 struct pf_parameter parameter;
1814 struct pf_map *pfm;
1815 struct pf_path *path = NULL;
1817 if (is_allied_city_tile(unit_tile(punit), unit_owner(punit))) {
1818 /* We're already on a city - don't go anywhere. */
1819 return NULL;
1822 goto_fill_parameter_base(&parameter, punit);
1823 pfm = pf_map_new(&parameter);
1825 pf_map_tiles_iterate(pfm, ptile, FALSE) {
1826 if (is_allied_city_tile(ptile, unit_owner(punit))) {
1827 path = pf_map_path(pfm, ptile);
1828 break;
1830 } pf_map_tiles_iterate_end;
1832 pf_map_destroy(pfm);
1834 return path;
1837 /**************************************************************************
1838 Finds penultimate tile on path for given unit going to ptile
1839 ***************************************************************************/
1840 struct tile *tile_before_end_path(struct unit *punit, struct tile *ptile)
1842 struct pf_parameter parameter;
1843 struct pf_map *pfm;
1844 struct tile *dtile;
1845 struct pf_path *path;
1847 goto_fill_parameter_base(&parameter, punit);
1848 parameter.move_rate = 0;
1849 parameter.is_pos_dangerous = NULL;
1850 parameter.get_moves_left_req = NULL;
1851 pfm = pf_map_new(&parameter);
1852 path = pf_map_path(pfm, ptile);
1853 if (path == NULL) {
1854 return NULL;
1856 if (path->length < 2) {
1857 dtile = NULL;
1858 } else {
1859 dtile = path->positions[path->length - 2].tile;
1861 pf_map_destroy(pfm);
1863 return dtile;