/**************************************************************** Callback from diplomat/spy dialog for "keep moving". (This should only occur when entering allied city.) *****************************************************************/ static void diplomat_keep_moving_callback(GtkWidget *w, gpointer data) { struct unit *punit; struct city *pcity; if ((punit = game_unit_by_number(diplomat_id)) && (pcity = game_city_by_number(diplomat_target_id)) && !same_pos(unit_tile(punit), city_tile(pcity))) { request_diplomat_action(DIPLOMAT_MOVE, diplomat_id, diplomat_target_id, 0); } gtk_widget_destroy(diplomat_dialog); }
/************************************************************************* Callback from diplomat/spy dialog for "keep moving". (This should only occur when entering the tile of an allied unit.) **************************************************************************/ static void diplomat_keep_moving_unit_callback(GtkWidget *w, gpointer data) { struct unit *punit; struct unit *tunit; if ((punit = game_unit_by_number(diplomat_id)) && (tunit = game_unit_by_number(diplomat_target_id[ATK_UNIT])) && !same_pos(unit_tile(punit), unit_tile(tunit))) { request_diplomat_action(DIPLOMAT_MOVE, diplomat_id, diplomat_target_id[ATK_UNIT], ATK_UNIT); } gtk_widget_destroy(diplomat_dialog); }
/**************************************************************** Callback from diplomat/spy dialog for "keep moving". (This should only occur when entering allied city.) *****************************************************************/ static int diplomat_keep_moving_callback(struct widget *pWidget) { if (Main.event.button.button == SDL_BUTTON_LEFT) { struct unit *punit; struct city *pcity; if ((punit = game_unit_by_number(pDiplomat_Dlg->diplomat_id)) && (pcity = game_city_by_number(pDiplomat_Dlg->diplomat_target_id)) && !same_pos(unit_tile(punit), city_tile(pcity))) { request_diplomat_action(DIPLOMAT_MOVE, pDiplomat_Dlg->diplomat_id, pDiplomat_Dlg->diplomat_target_id, 0); } popdown_diplomat_dialog(); } return -1; }
/************************************************************************** Callback from diplomat/spy dialog for "keep moving". (This should only occur when entering allied city.) **************************************************************************/ static void diplomat_keep_moving_callback(Widget w, XtPointer client_data, XtPointer call_data) { struct unit *punit; struct city *pcity; destroy_message_dialog(w); diplomat_dialog = NULL; if ((punit = game_unit_by_number(diplomat_id)) && (pcity = game_city_by_number(diplomat_target_id)) && !same_pos(unit_tile(punit), city_tile(pcity))) { request_diplomat_action(DIPLOMAT_MOVE, diplomat_id, diplomat_target_id, 0); } process_diplomat_arrival(NULL, 0); }
/************************************************************************ Trying to manage bombers and stuff. If we are in the open { if moving intelligently on a valid GOTO, { carry on doing it. } else { go refuel } } else { try to attack something } TODO: distant target selection, support for fuel > 2 ***********************************************************************/ void dai_manage_airunit(struct ai_type *ait, struct player *pplayer, struct unit *punit) { struct tile *dst_tile = unit_tile(punit); /* Loop prevention */ int moves = punit->moves_left; int id = punit->id; struct pf_parameter parameter; struct pf_map *pfm; struct pf_path *path; CHECK_UNIT(punit); if (!is_unit_being_refueled(punit)) { /* We are out in the open, what shall we do? */ if (punit->activity == ACTIVITY_GOTO /* We are on a GOTO. Check if it will get us anywhere */ && NULL != punit->goto_tile && !same_pos(unit_tile(punit), punit->goto_tile) && is_airunit_refuel_point(punit->goto_tile, pplayer, unit_type(punit), FALSE)) { pfm = pf_map_new(¶meter); path = pf_map_path(pfm, punit->goto_tile); if (path) { bool alive = adv_follow_path(punit, path, punit->goto_tile); pf_path_destroy(path); pf_map_destroy(pfm); if (alive && punit->moves_left > 0) { /* Maybe do something else. */ dai_manage_airunit(ait, pplayer, punit); } return; } pf_map_destroy(pfm); } else if ((dst_tile = find_nearest_airbase(punit, &path))) { /* Go refuelling */ if (!adv_follow_path(punit, path, dst_tile)) { pf_path_destroy(path); return; /* The unit died. */ } pf_path_destroy(path); } else { if (punit->fuel == 1) { UNIT_LOG(LOG_DEBUG, punit, "Oops, fallin outta the sky"); } def_ai_unit_data(punit, ait)->done = TRUE; /* Won't help trying again */ return; } } else if (punit->fuel == unit_type(punit)->fuel) { /* We only leave a refuel point when we are on full fuel */ if (find_something_to_bomb(ait, punit, &path, &dst_tile) > 0) { /* Found target, coordinates are in punit's goto_dest. * TODO: separate attacking into a function, check for the best * tile to attack from */ fc_assert_ret(path != NULL && dst_tile != NULL); if (!adv_follow_path(punit, path, dst_tile)) { pf_path_destroy(path); return; /* The unit died. */ } pf_path_destroy(path); /* goto would be aborted: "Aborting GOTO for AI attack procedures" * now actually need to attack */ /* We could use ai_military_findvictim here, but I don't trust it... */ unit_activity_handling(punit, ACTIVITY_IDLE); if (is_tiles_adjacent(unit_tile(punit), dst_tile)) { (void) unit_move_handling(punit, dst_tile, TRUE, FALSE); } } else if ((dst_tile = dai_find_strategic_airbase(ait, punit, &path))) { log_debug("%s will fly to (%i, %i) (%s) to fight there", unit_rule_name(punit), TILE_XY(dst_tile), tile_city(dst_tile) ? city_name(tile_city(dst_tile)) : ""); def_ai_unit_data(punit, ait)->done = TRUE; /* Wait for next turn */ if (!adv_follow_path(punit, path, dst_tile)) { pf_path_destroy(path); return; /* The unit died. */ } pf_path_destroy(path); } else { log_debug("%s cannot find anything to kill and is staying put", unit_rule_name(punit)); def_ai_unit_data(punit, ait)->done = TRUE; unit_activity_handling(punit, ACTIVITY_IDLE); } } if ((punit = game_unit_by_number(id)) != NULL && punit->moves_left > 0 && punit->moves_left != moves) { /* We have moved this turn, might have ended up stuck out in the fields * so, as a safety measure, let's manage again */ dai_manage_airunit(ait, pplayer, punit); } }