Freeciv-3.3: /fast/freeciv/nightly/main/client/goto.c Source File

Freeciv-3.3

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