Index: ai/aidiplomat.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/ai/aidiplomat.c,v retrieving revision 1.1 diff -u -r1.1 aidiplomat.c --- ai/aidiplomat.c 25 Nov 2002 19:18:08 -0000 1.1 +++ ai/aidiplomat.c 1 Dec 2002 15:10:20 -0000 @@ -503,11 +503,7 @@ continue; } /* Found someone! */ - handle_unit_activity_request(punit, ACTIVITY_IDLE); - punit->goto_dest_x = destx; - punit->goto_dest_y = desty; - if (do_unit_goto(punit, GOTO_MOVE_ANY, FALSE) == GR_DIED - || punit->moves_left == 0) { + if (!ai_unit_goto(punit, destx, desty) || punit->moves_left <= 0) { return FALSE; } if (diplomat_can_do_action(punit, DIPLOMAT_BRIBE, x, y)) { @@ -630,7 +626,7 @@ /* GOTO unless we want to stay */ if (!same_pos(punit->x, punit->y, ctarget->x, ctarget->y)) { - if (do_unit_goto(punit, GOTO_MOVE_ANY, FALSE) == GR_DIED) { + if (!ai_unit_gothere(punit)) { return; } } Index: ai/aitools.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/ai/aitools.c,v retrieving revision 1.62 diff -u -r1.62 aitools.c --- ai/aitools.c 14 Nov 2002 09:14:50 -0000 1.62 +++ ai/aitools.c 1 Dec 2002 15:10:20 -0000 @@ -112,6 +112,47 @@ } /************************************************************************** + This will eventually become the ferry-enabled goto. For now, it just + wraps ai_unit_goto() +**************************************************************************/ +bool ai_unit_gothere(struct unit *punit) +{ + assert(punit->goto_dest_x != -1 && punit->goto_dest_y != -1); + if (ai_unit_goto(punit, punit->goto_dest_x, punit->goto_dest_y)) { + return TRUE; /* ... and survived */ + } else { + return FALSE; /* we died */ + } +} + +/************************************************************************** + Go to specified destination but do not disturb existing role or activity + and do not clear the role's destination. Return FALSE iff we died. + + FIXME: add some logging functionality to replace GOTO_LOG() +**************************************************************************/ +bool ai_unit_goto(struct unit *punit, int x, int y) +{ + enum goto_result result; + int oldx = punit->goto_dest_x, oldy = punit->goto_dest_y; + enum unit_activity activity = punit->activity; + int sanity = punit->id; + + /* log error on same_pos with punit->x|y */ + punit->goto_dest_x = x; + punit->goto_dest_y = y; + handle_unit_activity_request(punit, ACTIVITY_GOTO); + result = do_unit_goto(punit, GOTO_MOVE_ANY, FALSE); + if ((punit = find_unit_by_id(sanity))) { + handle_unit_activity_request(punit, activity); + punit->goto_dest_x = oldx; + punit->goto_dest_y = oldy; + } + + return (result != GR_DIED); +} + +/************************************************************************** Ensure unit sanity by telling charge that we won't bodyguard it anymore, add and remove city spot reservation, and set destination. **************************************************************************/ Index: ai/aitools.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/ai/aitools.h,v retrieving revision 1.29 diff -u -r1.29 aitools.h --- ai/aitools.h 15 Nov 2002 22:15:01 -0000 1.29 +++ ai/aitools.h 1 Dec 2002 15:10:20 -0000 @@ -32,7 +32,10 @@ void destroy_unit_virtual(struct unit *punit); int is_stack_vulnerable(int x, int y); +bool ai_unit_gothere(struct unit *punit); +bool ai_unit_goto(struct unit *punit, int x, int y); void ai_unit_new_role(struct unit *punit, enum ai_unit_task task, int x, int y); + bool ai_unit_make_homecity(struct unit *punit, struct city *pcity); void ai_unit_attack(struct unit *punit, int x, int y); bool ai_unit_move(struct unit *punit, int x, int y); Index: ai/aiunit.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.c,v retrieving revision 1.230 diff -u -r1.230 aiunit.c --- ai/aiunit.c 25 Nov 2002 19:18:09 -0000 1.230 +++ ai/aiunit.c 1 Dec 2002 15:10:21 -0000 @@ -332,20 +332,11 @@ } iterate_outward_end; if (bestcost <= maxmoves * SINGLE_MOVE) { - enum goto_result result; - /* Go there! */ - punit->goto_dest_x = best_x; - punit->goto_dest_y = best_y; - set_unit_activity(punit, ACTIVITY_GOTO); - result = do_unit_goto(punit, GOTO_MOVE_ANY, FALSE); - if (result == GR_DIED) { + if (!ai_unit_goto(punit, best_x, best_y)) { /* We're dead. */ return FALSE; } - GOTO_LOG(LOG_DEBUG, punit, result, "exploring huts"); - - /* TODO: Take more advantage from the do_unit_goto() return value. */ if (punit->moves_left > 0) { /* We can still move on... */ @@ -511,19 +502,10 @@ } whole_map_iterate_end; if (most_unknown > 0) { - enum goto_result result; - /* Go there! */ - punit->goto_dest_x = best_x; - punit->goto_dest_y = best_y; - handle_unit_activity_request(punit, ACTIVITY_GOTO); - result = do_unit_goto(punit, GOTO_MOVE_ANY, FALSE); - if (result == GR_DIED) { + if (!ai_unit_goto(punit, best_x, best_y)) { return FALSE; } - GOTO_LOG(LOG_DEBUG, punit, result, "exploring territory"); - - /* TODO: Take more advantage from the do_unit_goto() return value. */ if (punit->moves_left > 0) { /* We can still move on... */ @@ -574,9 +556,7 @@ ai_military_gohome(pplayer, punit); } else { /* Also try take care of deliberately homeless units */ - punit->goto_dest_x = pcity->x; - punit->goto_dest_y = pcity->y; - (void) do_unit_goto(punit, GOTO_MOVE_ANY, FALSE); + (void) ai_unit_goto(punit, pcity->x, pcity->y); } } else { /* Sea travel */ @@ -585,12 +565,8 @@ UNIT_LOG(LOG_DEBUG, punit, "exploring unit wants a boat, going home"); ai_military_gohome(pplayer, punit); /* until then go home */ } else { - enum goto_result result; UNIT_LOG(LOG_DEBUG, punit, "sending explorer home by boat"); - punit->goto_dest_x = x; - punit->goto_dest_y = y; - result = do_unit_goto(punit, GOTO_MOVE_ANY, FALSE); - GOTO_LOG(LOG_DEBUG, punit, result, "explorer sail home"); + (void) ai_unit_goto(punit, x, y); } } } @@ -774,7 +750,6 @@ int which) { int x, y; - bool want_attack = (dest || punit->activity != ACTIVITY_GOTO); if (dest) { x = punit->goto_dest_x; @@ -789,7 +764,7 @@ if (pcity && pplayers_at_war(city_owner(pcity), unit_owner(punit)) && (pcity->ai.invasion & which) != which - && (want_attack || !has_defense(pcity))) { + && (dest || !has_defense(pcity))) { pcity->ai.invasion |= which; } } square_iterate_end; @@ -1117,13 +1092,7 @@ if (!same_pos(punit->x, punit->y, x, y)) { if (goto_is_sane(punit, x, y, TRUE)) { - enum goto_result result; - punit->goto_dest_x = x; - punit->goto_dest_y = y; - result = do_unit_goto(punit, GOTO_MOVE_ANY, FALSE); - if (result != GR_DIED) { - GOTO_LOG(LOGLEVEL_BODYGUARD, punit, result, "bodyguard meet"); - } + (void) ai_unit_goto(punit, x, y); } else { /* can't possibly get there to help */ ai_unit_new_role(punit, AIUNIT_NONE, -1, -1); @@ -1269,10 +1238,7 @@ freelog(LOG_DEBUG, "%s: %d@(%d, %d): Looking for BOAT (id=%d).", pplayer->name, punit->id, punit->x, punit->y, boatid); if (!same_pos(x, y, bx, by)) { - punit->goto_dest_x = bx; - punit->goto_dest_y = by; - set_unit_activity(punit, ACTIVITY_GOTO); - if (do_unit_goto(punit, GOTO_MOVE_ANY, FALSE) == GR_DIED) { + if (!ai_unit_goto(punit, bx, by)) { return -1; /* died */ } } @@ -1288,7 +1254,6 @@ /* the code that worked for settlers wasn't good for piles of cannons */ if (find_beachhead(punit, dest_x, dest_y, &ferryboat->goto_dest_x, &ferryboat->goto_dest_y) != 0) { -/* set_unit_activity(ferryboat, ACTIVITY_GOTO); -- Extremely bad!! -- Syela */ punit->goto_dest_x = dest_x; punit->goto_dest_y = dest_y; set_unit_activity(punit, ACTIVITY_SENTRY); /* anything but GOTO!! */ @@ -1303,7 +1268,7 @@ if (def) set_unit_activity(def, ACTIVITY_SENTRY); } unit_list_iterate_end; /* passengers are safely stowed away */ - if (do_unit_goto(ferryboat, GOTO_MOVE_ANY, FALSE) == GR_DIED) { + if (!ai_unit_goto(ferryboat, dest_x, dest_y)) { return -1; /* died */ } set_unit_activity(punit, ACTIVITY_IDLE); @@ -1349,8 +1314,7 @@ unit_type(punit)->name, punit->id, punit->x, punit->y, dest_x, dest_y); } - set_unit_activity(punit, ACTIVITY_GOTO); - if (do_unit_goto(punit, GOTO_MOVE_ANY, FALSE) == GR_DIED) { + if (!ai_unit_goto(punit, dest_x, dest_y)) { return -1; /* died */ } /* liable to bump into someone that will kill us. Should avoid? */ @@ -1587,12 +1551,8 @@ /* aggro defense goes here -- Syela */ punit = ai_military_rampage(punit, 2); /* 2 is better than pillage */ } else { - freelog(LOG_DEBUG, "GOHOME(%d,%d)", - punit->goto_dest_x, punit->goto_dest_y); - punit->goto_dest_x=pcity->x; - punit->goto_dest_y=pcity->y; - set_unit_activity(punit, ACTIVITY_GOTO); - (void) do_unit_goto(punit, GOTO_MOVE_ANY, FALSE); + UNIT_LOG(LOG_DEBUG, punit, "GOHOME"); + (void) ai_unit_goto(punit, pcity->x, pcity->y); } } else { handle_unit_activity_request(punit, ACTIVITY_FORTIFYING); @@ -2030,7 +1990,7 @@ if (is_sailing_unit(punit) && find_nearest_friendly_port(punit)) { /* Sail somewhere */ - (void) do_unit_goto(punit, GOTO_MOVE_ANY, FALSE); + (void) ai_unit_gothere(punit); } else if (!is_barbarian(pplayer)) { /* Nothing else to do. Worst case, this function will send us back home */ @@ -2082,10 +2042,10 @@ && unit_flag(punit, F_HELP_WONDER) && build_points_left(pcity) > (pcity->shield_surplus * 2)) { if (!same_pos(pcity->x, pcity->y, punit->x, punit->y)) { - if (punit->moves_left == 0) + if (punit->moves_left == 0) { return; - auto_settler_do_goto(pplayer, punit, pcity->x, pcity->y); - handle_unit_activity_request(punit, ACTIVITY_IDLE); + } + (void) ai_unit_goto(punit, pcity->x, pcity->y); } else { /* * We really don't want to just drop all caravans in immediately. @@ -2119,8 +2079,10 @@ if (pcity) { if (!same_pos(pcity->x, pcity->y, punit->x, punit->y)) { - if (punit->moves_left == 0) return; - auto_settler_do_goto(pplayer, punit, pcity->x, pcity->y); + if (punit->moves_left == 0) { + return; + } + (void) ai_unit_goto(punit, pcity->x, pcity->y); } else { req.unit_id = punit->id; req.city_id = pcity->id; @@ -2170,12 +2132,12 @@ if (p != 0) { freelog(LOG_DEBUG, "%s#%d@(%d,%d), p=%d, n=%d", unit_name(punit->type), punit->id, punit->x, punit->y, p, n); - if (punit->moves_left > 0 && n != 0) - (void) do_unit_goto(punit, GOTO_MOVE_ANY, FALSE); - else if (n == 0 && !map_get_city(punit->x, punit->y)) { /* rest in a city, for unhap */ + if (punit->moves_left > 0 && n != 0) { + (void) ai_unit_gothere(punit); + } else if (n == 0 && !map_get_city(punit->x, punit->y)) { /* rest in a city, for unhap */ x = punit->goto_dest_x; y = punit->goto_dest_y; if (find_nearest_friendly_port(punit) - && do_unit_goto(punit, GOTO_MOVE_ANY, FALSE) == GR_DIED) { + && !ai_unit_gothere(punit)) { return; /* oops! */ } punit->goto_dest_x = x; punit->goto_dest_y = y; @@ -2230,12 +2192,9 @@ /* Pickup is within 4 turns to grab, so move it! */ punit->goto_dest_x = x; punit->goto_dest_y = y; - set_unit_activity(punit, ACTIVITY_GOTO); UNIT_LOG(LOG_DEBUG, punit, "Found a friend and going to him @(%d, %d)", x, y); - if (do_unit_goto(punit, GOTO_MOVE_ANY, FALSE) != GR_DIED) { - set_unit_activity(punit, ACTIVITY_IDLE); - } + (void) ai_unit_gothere(punit); return; } @@ -2248,9 +2207,8 @@ unit_move_turns(punit, pcity->x, pcity->y) < p) { punit->goto_dest_x = pcity->x; punit->goto_dest_y = pcity->y; - set_unit_activity(punit, ACTIVITY_GOTO); UNIT_LOG(LOG_DEBUG, punit, "No friends. Going home."); - (void) do_unit_goto(punit, GOTO_MOVE_ANY, FALSE); + (void) ai_unit_gothere(punit); return; } } @@ -2547,8 +2505,7 @@ && !same_pos(closest_unit->x, closest_unit->y, leader->x, leader->y) && (map_get_continent(leader->x, leader->y) == map_get_continent(closest_unit->x, closest_unit->y))) { - auto_settler_do_goto(pplayer, leader, closest_unit->x, closest_unit->y); - handle_unit_activity_request(leader, ACTIVITY_IDLE); + (void) ai_unit_goto(leader, closest_unit->x, closest_unit->y); return; /* sticks better to own units with this -- jk */ } @@ -2618,7 +2575,7 @@ freelog(LOG_DEBUG, "Fleeing to %d, %d.", safest_x, safest_y); last_x = leader->x; last_y = leader->y; - auto_settler_do_goto(pplayer, leader, safest_x, safest_y); + (void) ai_unit_goto(leader, safest_x, safest_y); if (same_pos(leader->x, leader->y, last_x, last_y)) { /* Deep inside the goto handling code, in server/unithand.c::handle_unite_move_request(), the server Index: server/settlers.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/settlers.c,v retrieving revision 1.152 diff -u -r1.152 settlers.c --- server/settlers.c 14 Nov 2002 09:15:05 -0000 1.152 +++ server/settlers.c 1 Dec 2002 15:10:23 -0000 @@ -732,16 +732,12 @@ void auto_settler_do_goto(struct player *pplayer, struct unit *punit, int x, int y) { - enum goto_result gotores; - CHECK_MAP_POS(x, y); punit->goto_dest_x = x; punit->goto_dest_y = y; set_unit_activity(punit, ACTIVITY_GOTO); send_unit_info(NULL, punit); - gotores = do_unit_goto(punit, GOTO_MOVE_ANY, FALSE); - - if (gotores != GR_DIED) { + if (!ai_unit_gothere(punit)) { freelog(LOG_DEBUG, "%s: %s (%d@%d,%d) did settler goto to %s towards " "(%d,%d) with result %d", pplayer->name, unit_type(punit)->name, punit->id, punit->x, punit->y, get_activity_text(punit->activity),