<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 Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev