Index: ai/advmilitary.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/ai/advmilitary.c,v retrieving revision 1.128 diff -u -r1.128 advmilitary.c --- ai/advmilitary.c 2003/01/02 11:59:28 1.128 +++ ai/advmilitary.c 2003/01/05 17:41:42 @@ -1295,11 +1295,10 @@ break; case HELI_MOVING: case AIR_MOVING: - /* Should we build airports by default? */ - /* if (player_knows_improvement_tech(pplayer, B_AIRPORT)) { - choice->choice = B_AIRPORT; - choice->type = CT_BUILDING; - } */ + if (player_knows_improvement_tech(pplayer, B_AIRPORT)) { + choice->choice = B_AIRPORT; + choice->type = CT_BUILDING; + } break; default: freelog(LOG_ERROR, "Unknown move_type in adjust_ai_unit_choice"); Index: ai/aiunit.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.c,v retrieving revision 1.248 diff -u -r1.248 aiunit.c --- ai/aiunit.c 2003/01/02 11:59:29 1.248 +++ ai/aiunit.c 2003/01/05 17:41:43 @@ -88,6 +88,65 @@ Unit_Type_id simple_ai_types[U_LAST]; /************************************************************************** + Move defenders around with airports. Since this expends all our + movement, a valid question is - why don't we do this on turn end? + That's because we want to avoid emergency actions to protect the city + during the turn if that isn't necessary. +**************************************************************************/ +static void ai_airlift(struct player *pplayer) +{ + struct city *most_needed; + int comparison; + struct city *least_needed; + struct unit *transported; + + do { + most_needed = NULL; + comparison = 0; + least_needed = NULL; + transported = NULL; + + city_list_iterate(pplayer->cities, pcity) { + if (pcity->ai.urgency > comparison && pcity->airlift) { + comparison = pcity->ai.urgency; + most_needed = pcity; + } + } city_list_iterate_end; + if (!most_needed) { + comparison = 0; + city_list_iterate(pplayer->cities, pcity) { + if (pcity->ai.danger > comparison && pcity->airlift) { + comparison = pcity->ai.danger; + most_needed = pcity; + } + } city_list_iterate_end; + } + if (!most_needed) { + return; + } + comparison = 0; + unit_list_iterate(pplayer->units, punit) { + struct tile *ptile = map_get_tile(punit->x, punit->y); + + if (ptile->city && ptile->city->ai.urgency == 0 + && ptile->city->ai.danger - DEFENCE_POWER(punit) < comparison + && unit_can_airlift_to(punit, most_needed) + && DEFENCE_POWER(punit) > 2 + && IS_ATTACKER(punit)) { + comparison = ptile->city->ai.danger; + transported = punit; + } + } unit_list_iterate_end; + if (!transported) { + return; + } + UNIT_LOG(LOG_DEBUG, transported, "will be airlifted to defend %s", + most_needed->name); + do_airline(transported, most_needed); + } while (TRUE); +} + +/************************************************************************** Similar to is_my_zoc(), but with some changes: - destination (x0,y0) need not be adjacent? - don't care about some directions? @@ -2586,6 +2645,7 @@ **************************************************************************/ void ai_manage_units(struct player *pplayer) { + ai_airlift(pplayer); unit_list_iterate_safe(pplayer->units, punit) { ai_manage_unit(pplayer, punit); } unit_list_iterate_safe_end;