/****************************************************************
  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);
}
Exemple #2
0
/*************************************************************************
  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);
}
Exemple #5
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(&parameter);
      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);
  }

}