<URL: http://bugs.freeciv.org/Ticket/Display.html?id=40169 >
Somehow ferry movement caused alliance to break (by making new
contact). This caused units, including ferry, to bounce. Pathfinding
crashed because unit was no longer on path.
Fix attached.
- ML
diff -Nurd -X.diff_ignore freeciv/ai/aiferry.c freeciv/ai/aiferry.c
--- freeciv/ai/aiferry.c 2008-01-20 04:03:28.000000000 +0200
+++ freeciv/ai/aiferry.c 2008-03-27 06:36:01.000000000 +0200
@@ -553,7 +553,11 @@
* has run out of movement points */
struct tile *next_tile;
- pft_advance_path(path, passenger->tile);
+ if (!pft_advance_path(path, passenger->tile)) {
+ /* Somehow we got thrown away from our route.
+ * This can happen if our movement caused alliance breakup. */
+ return alive;
+ }
next_tile = path->positions[1].tile;
if (!is_ocean_tile(next_tile)) {
UNIT_LOG(LOG_DEBUG, passenger, "Our boat has arrived "
diff -Nurd -X.diff_ignore freeciv/common/aicore/pf_tools.c freeciv/common/aicore/pf_tools.c
--- freeciv/common/aicore/pf_tools.c 2008-03-08 16:32:47.000000000 +0200
+++ freeciv/common/aicore/pf_tools.c 2008-03-27 06:36:21.000000000 +0200
@@ -869,17 +869,19 @@
/****************************************************************************
Remove the part of a path leading up to a given tile.
- The given tile must be on the path. If it is on the path more than once
+ If given tile is on the path more than once
then the first occurrance will be the one used.
+ If tile is not on the path at all, returns FALSE and
+ path is not changed at all.
****************************************************************************/
-void pft_advance_path(struct pf_path *path, struct tile *ptile)
+bool pft_advance_path(struct pf_path *path, struct tile *ptile)
{
int i;
struct pf_position *new_positions;
- for (i = 0; i < path->length; i++) {
- if (path->positions[i].tile == ptile) {
- break;
+ for (i = 0; path->positions[i].tile != ptile ; i++) {
+ if (i >= path->length) {
+ return FALSE;
}
}
assert(i < path->length);
@@ -889,4 +891,6 @@
path->length * sizeof(*path->positions));
free(path->positions);
path->positions = new_positions;
+
+ return TRUE;
}
diff -Nurd -X.diff_ignore freeciv/common/aicore/pf_tools.h freeciv/common/aicore/pf_tools.h
--- freeciv/common/aicore/pf_tools.h 2007-09-14 14:51:34.000000000 +0300
+++ freeciv/common/aicore/pf_tools.h 2008-03-27 06:36:01.000000000 +0200
@@ -40,7 +40,7 @@
struct pf_path *pft_concat(struct pf_path *dest_path,
const struct pf_path *src_path);
-void pft_advance_path(struct pf_path *path,
+bool pft_advance_path(struct pf_path *path,
struct tile *ptile);
void pft_fill_unit_parameter(struct pf_parameter *parameter,
struct unit *punit);
diff -Nurd -X.diff_ignore freeciv/server/unithand.c freeciv/server/unithand.c
--- freeciv/server/unithand.c 2008-03-08 16:32:28.000000000 +0200
+++ freeciv/server/unithand.c 2008-03-27 06:36:01.000000000 +0200
@@ -1137,8 +1137,9 @@
}
/**************************************************************************
- Will try to move to/attack the tile dest_x,dest_y. Returns true if this
- could be done, false if it couldn't for some reason.
+ Will try to move to/attack the tile dest_x,dest_y. Returns TRUE if this
+ could be done, FALSE if it couldn't for some reason. Even if this
+ returns TRUE, unit may have died upon arrival to new tile.
'igzoc' means ignore ZOC rules - not necessary for igzoc units etc, but
done in some special cases (moving barbarians out of initial hut).
_______________________________________________
Freeciv-dev mailing list
[email protected]
https://mail.gna.org/listinfo/freeciv-dev