[Freeciv-Dev] (PR#10830) Trirem doesn't want to move
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://rt.freeciv.org/Ticket/Display.html?id=10830 >
> [jdorje - Fri Nov 05 15:35:39 2004]:
>
> Gregory Berkolaiko wrote:
>
> > Doing it with a high move-cost will break the "waiting" logic. So we
> > will have triremes sinking again even when there is only one dangerous
> > tile between two oceans.
>
> What about using extra cost (EC) for this?
EC is awarded always, whether the unit ends its move on a tile or not.
And doing it otherwise is impossible outside danger framework, so we get
a loop.
Anyway, I hacked together a patch which does the following:
1. you put a unit into the goto mode (pressing G or via the menu)
2. move your cursor to a dangerous tile you really want to get to
3. press "f" to cycle through several available paths
sometimes some paths are obviously better than the others, I cannot do
anything about it.
it would be great if we could highlight:
a) the last danger segment
b) the points where we wait <- this one should have been done long ago.
currently you cannot make the unit actually take the selected path, but
it would be easy to change.
I would like the client people to
i) think about the interface (maybe press some mouse key instead of f?)
ii) fix my surely barbaric changes to the client
Then I can clean up my PF changes and hopefully we'll have a solution to
this rather annoying problem.
G.
Index: client/control.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/control.c,v
retrieving revision 1.150
diff -u -r1.150 control.c
--- client/control.c 13 Nov 2004 08:27:46 -0000 1.150
+++ client/control.c 28 Nov 2004 02:40:28 -0000
@@ -1837,6 +1837,21 @@
}
/**************************************************************************
+ Force displaying path to a dangerous tile
+**************************************************************************/
+void key_unit_force_goto(struct tile *ptile)
+{
+ struct unit *punit = punit_focus;
+
+ if (!punit || hover_state != HOVER_GOTO) {
+ return;
+ } else if (!is_air_unit(punit) && !is_heli_unit(punit)) {
+ assert(goto_is_active());
+ goto_force_path(ptile);
+ }
+}
+
+/**************************************************************************
...
**************************************************************************/
void key_unit_goto(void)
Index: client/control.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/control.h,v
retrieving revision 1.45
diff -u -r1.45 control.h
--- client/control.h 29 Sep 2004 02:24:19 -0000 1.45
+++ client/control.h 28 Nov 2004 02:40:28 -0000
@@ -149,6 +149,7 @@
void key_unit_fortify(void);
void key_unit_fortress(void);
void key_unit_goto(void);
+void key_unit_force_goto(struct tile *ptile);
void key_unit_homecity(void);
void key_unit_irrigate(void);
void key_unit_mine(void);
Index: client/goto.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/goto.c,v
retrieving revision 1.79
diff -u -r1.79 goto.c
--- client/goto.c 22 Nov 2004 19:14:41 -0000 1.79
+++ client/goto.c 28 Nov 2004 02:40:29 -0000
@@ -125,29 +125,15 @@
}
/**********************************************************************
- Change the destination of the last part to the given position if a
- path can be found. If not the destination is set to the start.
+ Draw a path, trying to reuse already drawn parts. Record the new
+ path and update the part structure.
***********************************************************************/
-static void update_last_part(struct tile *ptile)
+static void put_path(struct tile *ptile, struct pf_path *new_path)
{
struct part *p = &goto_map.parts[goto_map.num_parts - 1];
- struct pf_path *new_path;
struct tile *old_tile = p->start_tile;
int i, start_index = 0;
- freelog(LOG_DEBUG, "update_last_part(%d,%d) old (%d,%d)-(%d,%d)",
- TILE_XY(ptile), TILE_XY(p->start_tile), TILE_XY(p->end_tile));
- new_path = pf_get_path(p->map, ptile);
-
- if (!new_path) {
- freelog(PATH_LOG_LEVEL, " no path found");
- reset_last_part();
- return;
- }
-
- freelog(PATH_LOG_LEVEL, " path found:");
- pf_print_path(PATH_LOG_LEVEL, new_path);
-
if (p->path) {
/* We had a path drawn already. Determine how much of it we can reuse
* in drawing the new path. */
@@ -212,6 +198,57 @@
/* Refresh tiles so turn information is shown. */
refresh_tile_mapcanvas(old_tile, FALSE);
refresh_tile_mapcanvas(ptile, FALSE);
+
+}
+
+/**********************************************************************
+ Change the destination of the last part to the given position if a
+ path can be found. If not the destination is set to the start.
+***********************************************************************/
+static void update_last_part(struct tile *ptile)
+{
+ struct part *p = &goto_map.parts[goto_map.num_parts - 1];
+ struct pf_path *new_path;
+
+ freelog(LOG_DEBUG, "update_last_part(%d,%d) old (%d,%d)-(%d,%d)",
+ TILE_XY(ptile), TILE_XY(p->start_tile), TILE_XY(p->end_tile));
+ new_path = pf_get_path(p->map, ptile);
+
+ if (!new_path) {
+ freelog(PATH_LOG_LEVEL, " no path found");
+ reset_last_part();
+ return;
+ }
+
+ freelog(PATH_LOG_LEVEL, " path found:");
+ pf_print_path(PATH_LOG_LEVEL, new_path);
+
+ put_path(ptile, new_path);
+}
+
+/**********************************************************************
+ Force dsiplay of the path to a dangerous tile
+***********************************************************************/
+void goto_force_path(struct tile *ptile)
+{
+ struct part *p = &goto_map.parts[goto_map.num_parts - 1];
+ struct pf_path *path;
+
+ path = pf_force_get_path(p->map, ptile);
+
+ if (!path) {
+ /* Try resetting */
+ struct pf_parameter parameter = *pf_get_parameter(p->map);
+
+ pf_destroy_map(p->map);
+ pf_create_map(¶meter);
+ path = pf_force_get_path(p->map, ptile);
+ }
+
+ if (path) {
+ pf_print_path(LOG_NORMAL, path);
+ put_path(ptile, path);
+ }
}
/**********************************************************************
Index: client/goto.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/goto.h,v
retrieving revision 1.16
diff -u -r1.16 goto.h
--- client/goto.h 29 Sep 2004 02:24:19 -0000 1.16
+++ client/goto.h 28 Nov 2004 02:40:29 -0000
@@ -27,6 +27,7 @@
void goto_add_waypoint(void);
bool goto_pop_waypoint(void);
+void goto_force_path(struct tile *ptile);
void draw_line(struct tile *dest_tile);
bool is_drawn_line(struct tile *dest_tile, int dir);
Index: client/gui-gtk-2.0/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/gui_main.c,v
retrieving revision 1.96
diff -u -r1.96 gui_main.c
--- client/gui-gtk-2.0/gui_main.c 26 Nov 2004 22:28:42 -0000 1.96
+++ client/gui-gtk-2.0/gui_main.c 28 Nov 2004 02:40:29 -0000
@@ -436,6 +436,17 @@
key_city_workers(w, ev);
break;
+ case GDK_f:
+ {
+ int x, y;
+ struct tile *ptile;
+
+ gdk_window_get_pointer(map_canvas->window, &x, &y, NULL);
+ ptile = canvas_pos_to_tile(x, y);
+ key_unit_force_goto(ptile);
+ break;
+ }
+
case GDK_KP_Divide:
key_quickselect(SELECT_SEA);
break;
Index: common/aicore/path_finding.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/aicore/path_finding.c,v
retrieving revision 1.27
diff -u -r1.27 path_finding.c
--- common/aicore/path_finding.c 27 Nov 2004 22:11:09 -0000 1.27
+++ common/aicore/path_finding.c 28 Nov 2004 02:40:29 -0000
@@ -109,11 +109,12 @@
struct danger_node *d_lattice; /* Lattice with danger stuff */
};
-static bool danger_iterate_map(struct pf_map *pf_map);
+static bool danger_iterate_map(struct pf_map *pf_map, bool return_dangerous);
static struct pf_path* danger_construct_path(const struct pf_map *pf_map,
- struct tile *ptile);
-static struct pf_path *danger_get_path(struct pf_map *pf_map,
- struct tile *ptile);
+ struct tile *ptile,
+ struct pf_danger_pos *d_seg);
+static struct pf_path *danger_get_path(struct pf_map *pf_map,
+ struct tile *ptile);
/* =================== manipulating the cost ===================== */
@@ -315,7 +316,7 @@
if (pf_map->params->is_pos_dangerous) {
/* It's a lot different if is_pos_dangerous is defined */
- return danger_iterate_map(pf_map);
+ return danger_iterate_map(pf_map, FALSE);
}
if (pf_map->params->get_costs) {
@@ -657,7 +658,7 @@
return construct_path(pf_map, pf_map->tile);
} else {
/* It's very different in the presence of danger */
- return danger_construct_path(pf_map, pf_map->tile);
+ return danger_construct_path(pf_map, pf_map->tile, NULL);
}
}
@@ -762,11 +763,10 @@
/***********************************************************************
Creating path segment going back from d_node1 to a safe tile.
***********************************************************************/
-static void create_danger_segment(struct pf_map *pf_map, enum direction8 dir,
+static void create_danger_segment(struct pf_map *pf_map, struct tile *ptile,
struct danger_node *d_node1, int length)
{
int i;
- struct tile *ptile = pf_map->tile;
struct pf_node *node = &pf_map->lattice[ptile->index];
/* Allocating memory */
@@ -855,7 +855,7 @@
across danger, supply get_EC which returns small extra on
dangerous tiles.
*****************************************************************************/
-static bool danger_iterate_map(struct pf_map *pf_map)
+static bool danger_iterate_map(struct pf_map *pf_map, bool return_dangerous)
{
mapindex_t index;
struct pf_node *node = &pf_map->lattice[pf_map->tile->index];
@@ -946,7 +946,7 @@
}
if (d_node->is_dangerous) {
/* Transition from red to blue, need to record the path back */
- create_danger_segment(pf_map, dir, d_node1,
+ create_danger_segment(pf_map, pf_map->tile, d_node1,
d_node->segment_length);
} else {
/* We don't consider waiting to get to a safe tile as
@@ -1028,12 +1028,14 @@
/* We've already returned this node once, skip it */
freelog(LOG_DEBUG, "Considering waiting at (%d, %d)",
pf_map->tile->x, pf_map->tile->y);
- return danger_iterate_map(pf_map);
+ return danger_iterate_map(pf_map, return_dangerous);
} else if (pf_map->d_lattice[index].is_dangerous) {
/* We don't return dangerous tiles */
- freelog(LOG_DEBUG, "Reached dangerous tile (%d, %d)",
- pf_map->tile->x, pf_map->tile->y);
- return danger_iterate_map(pf_map);
+ freelog(LOG_DEBUG, "Reached dangerous (%d, %d); cost %d, moves left %d",
+ pf_map->tile->x, pf_map->tile->y, pf_map->lattice[index].cost,
+ get_moves_left(pf_map, pf_map->lattice[index].cost));
+ return (return_dangerous ? TRUE
+ : danger_iterate_map(pf_map, return_dangerous));
} else {
/* Just return it */
return TRUE;
@@ -1045,16 +1047,16 @@
NB: will only find paths to safe tiles!
*******************************************************************/
static struct pf_path *danger_construct_path(const struct pf_map *pf_map,
- struct tile *ptile)
+ struct tile *ptile,
+ struct pf_danger_pos *d_seg)
{
struct pf_path *path = fc_malloc(sizeof(*path));
int i;
enum direction8 dir_next = -1;
- struct pf_danger_pos *danger_seg = NULL; /* For danger segments */
- int segment_index = -1; /* For danger segments */
- bool waited = FALSE;
+ int segment_index = 0; /* For danger segments */
struct pf_node *node = &pf_map->lattice[ptile->index];
struct danger_node *d_node = &pf_map->d_lattice[ptile->index];
+ bool waited = (d_seg ? d_node->waited : FALSE);
if (pf_map->params->turn_mode != TM_BEST_TIME &&
pf_map->params->turn_mode != TM_WORST_TIME) {
@@ -1098,9 +1100,9 @@
path->positions[i].total_EC = node->extra_cost;
} else {
/* When on dangerous tiles, must have a valid danger segment */
- assert(danger_seg != NULL);
- path->positions[i].total_MC = danger_seg[segment_index].cost;
- path->positions[i].total_EC = danger_seg[segment_index].extra_cost;
+ assert(d_seg != NULL);
+ path->positions[i].total_MC = d_seg[segment_index].cost;
+ path->positions[i].total_EC = d_seg[segment_index].extra_cost;
}
path->positions[i].turn = get_turn(pf_map, path->positions[i].total_MC);
path->positions[i].moves_left
@@ -1122,12 +1124,12 @@
dir_next = node->dir_to_here;
/* d_node->danger_segment is the indicator of what lies ahead
* if it's non-NULL, we are entering a danger segment,
- * if it's NULL, we are not on one so danger_seg should be NULL */
- danger_seg = d_node->danger_segment;
+ * if it's NULL, we are not on one so d_seg should be NULL */
+ d_seg = d_node->danger_segment;
segment_index = 0;
} else {
/* We are in a danger segment */
- dir_next = danger_seg[segment_index].dir;
+ dir_next = d_seg[segment_index].dir;
segment_index++;
}
@@ -1151,6 +1153,14 @@
mapindex_t index = ptile->index;
utiny_t status = pf_map->status[index];
struct danger_node *d_node = &pf_map->d_lattice[index];
+
+ /* Initialise target tile to set the is_dangerous field */
+ if (pf_map->status[index] == NS_UNINIT) {
+ struct pf_node *node = &pf_map->lattice[index];
+
+ init_node(pf_map, node, ptile);
+ init_danger_node(pf_map, d_node, node, ptile);
+ }
if (d_node->is_dangerous) {
/* "Best" path to a dangerous tile is undefined */
@@ -1161,13 +1171,55 @@
if (status == NS_PROCESSED || status == NS_WAITING
|| same_pos(ptile, pf_map->tile)) {
/* We already reached (x,y) */
- return danger_construct_path(pf_map, ptile);
+ return danger_construct_path(pf_map, ptile, NULL);
}
while (pf_next(pf_map)) {
if (same_pos(ptile, pf_map->tile)) {
/* That's the one */
- return danger_construct_path(pf_map, ptile);
+ return danger_construct_path(pf_map, ptile, NULL);
+ }
+ }
+
+ return NULL;
+}
+
+/************************************************************************
+ Force the path to a dangerous tile.
+************************************************************************/
+struct pf_path *pf_force_get_path(struct pf_map *pf_map, struct tile *ptile)
+{
+ mapindex_t index = ptile->index;
+ utiny_t status = pf_map->status[index];
+ struct danger_node *d_node = &pf_map->d_lattice[index];
+ struct pf_node *node = &pf_map->lattice[index];
+
+ /* Initialise target tile to set the is_dangerous field */
+ if (status == NS_UNINIT) {
+ struct pf_node *node = &pf_map->lattice[index];
+
+ init_node(pf_map, node, ptile);
+ init_danger_node(pf_map, d_node, node, ptile);
+ }
+
+ if (!d_node->is_dangerous) {
+ /* Dialed a wrong number */
+ return NULL;
+ }
+
+ while (danger_iterate_map(pf_map, TRUE)) {
+ if (same_pos(ptile, pf_map->tile)) {
+ /* That's the one */
+ struct tile *itile = ptile;
+ struct pf_path *path;
+ int i;
+
+ create_danger_segment(pf_map, ptile, d_node, d_node->segment_length);
+ path = danger_construct_path(pf_map, ptile, d_node->danger_segment);
+ free(d_node->danger_segment);
+ d_node->danger_segment = NULL;
+
+ return path;
}
}
Index: common/aicore/path_finding.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/aicore/path_finding.h,v
retrieving revision 1.10
diff -u -r1.10 path_finding.h
--- common/aicore/path_finding.h 29 Sep 2004 02:24:23 -0000 1.10
+++ common/aicore/path_finding.h 28 Nov 2004 02:40:29 -0000
@@ -426,4 +426,7 @@
/* Return the current parameters for the given map. */
struct pf_parameter *pf_get_parameter(struct pf_map *map);
+/* Force return of a path to a dangerous tile */
+struct pf_path *pf_force_get_path(struct pf_map *pf_map, struct tile *ptile);
+
#endif
- [Freeciv-Dev] Re: (PR#10830) Trirem doesn't want to move, (continued)
- [Freeciv-Dev] Re: (PR#10830) Trirem doesn't want to move, Christian Knoke, 2004/11/03
- [Freeciv-Dev] Re: (PR#10830) Trirem doesn't want to move, François-Xavier Coudert, 2004/11/03
- [Freeciv-Dev] Re: (PR#10830) Trirem doesn't want to move, Vasco Alexandre da Silva Costa, 2004/11/03
- [Freeciv-Dev] Re: (PR#10830) Trirem doesn't want to move, Jason Short, 2004/11/03
- [Freeciv-Dev] Re: (PR#10830) Trirem doesn't want to move, Jason Short, 2004/11/03
- [Freeciv-Dev] Re: (PR#10830) Trirem doesn't want to move, Mike Kaufman, 2004/11/03
- [Freeciv-Dev] Re: (PR#10830) Trirem doesn't want to move, Christian Knoke, 2004/11/03
- [Freeciv-Dev] Re: (PR#10830) Trirem doesn't want to move, François-Xavier Coudert, 2004/11/04
- [Freeciv-Dev] (PR#10830) Trirem doesn't want to move, Gregory Berkolaiko, 2004/11/04
- [Freeciv-Dev] Re: (PR#10830) Trirem doesn't want to move, Jason Short, 2004/11/05
- [Freeciv-Dev] (PR#10830) Trirem doesn't want to move,
Gregory Berkolaiko <=
|
|