Example #1
0
/***********************************************************************
  Iterates through reachable cities and appraises them as a possible 
  base for air operations by (air)unit punit.  Returns NULL if not
  found.  The path is stored in the path argument if not NULL.
**********************************************************************/
static struct tile *dai_find_strategic_airbase(struct ai_type *ait,
                                               const struct unit *punit,
                                               struct pf_path **path)
{
  struct player *pplayer = unit_owner(punit);
  struct pf_parameter parameter;
  struct pf_map *pfm;
  struct tile *best_tile = NULL;
  struct city *pcity;
  struct unit *pvirtual = NULL;
  int best_worth = 0, target_worth;

  pft_fill_unit_parameter(&parameter, punit);
  pfm = pf_map_new(&parameter);
  pf_map_move_costs_iterate(pfm, ptile, move_cost, FALSE) {
    if (move_cost >= punit->moves_left) {
      break; /* Too far! */
    }

    if (!is_airunit_refuel_point(ptile, pplayer,
                                 unit_type(punit), FALSE)) {
      continue; /* Cannot refuel here. */
    }

    if ((pcity = tile_city(ptile))
        && def_ai_city_data(pcity, ait)->grave_danger != 0) {
      best_tile = ptile;
      break; /* Fly there immediately!! */
    }

    if (!pvirtual) {
      pvirtual =
        unit_virtual_create(pplayer,
                            player_city_by_number(pplayer, punit->homecity),
                            unit_type(punit), punit->veteran);
    }

    unit_tile_set(pvirtual, ptile);
    target_worth = find_something_to_bomb(ait, pvirtual, NULL, NULL);
    if (target_worth > best_worth) {
      /* It's either a first find or it's better than the previous. */
      best_worth = target_worth;
      best_tile = ptile;
      /* We can still look for something better. */
    }
  } pf_map_move_costs_iterate_end;

  if (pvirtual) {
    unit_virtual_destroy(pvirtual);
  }

  if (path) {
    /* Stores the path. */
    *path = best_tile ? pf_map_path(pfm, best_tile) : NULL;
  }
  pf_map_destroy(pfm);

  return best_tile;
}
Example #2
0
/*****************************************************************************
  Find best tile the paratrooper should jump to.
*****************************************************************************/
static struct tile *find_best_tile_to_paradrop_to(struct ai_type *ait,
                                                  struct unit *punit)
{
  int best = 0;
  int val;
  struct tile* best_tile = NULL;
  int range = unit_type(punit)->paratroopers_range;
  struct city* acity;
  struct player* pplayer = unit_owner(punit);

  /* First, we search for undefended cities in danger */
  square_iterate(unit_tile(punit), range, ptile) {
    if (!map_is_known(ptile, pplayer)) {
      continue;
    }
  
    acity = tile_city(ptile);
    if (acity && city_owner(acity) == unit_owner(punit)
        && unit_list_size(ptile->units) == 0) {
      val = city_size_get(acity) * def_ai_city_data(acity, ait)->urgency;
      if (val > best) {
	best = val;
	best_tile = ptile;
      }
    }
  } square_iterate_end;
  
  if (best_tile != NULL) {
    acity = tile_city(best_tile);
    UNIT_LOG(LOGLEVEL_PARATROOPER, punit, 
             "Choose to jump in order to protect allied city %s (%d %d). "
	     "Benefit: %d",
	     city_name(acity), TILE_XY(best_tile), best);
    return best_tile;
  }

  /* Second, we search for undefended enemy cities */
  square_iterate(unit_tile(punit), range, ptile) {
    acity = tile_city(ptile);
    if (acity && pplayers_at_war(unit_owner(punit), city_owner(acity)) &&
        (unit_list_size(ptile->units) == 0)) {
      if (!map_is_known_and_seen(ptile, pplayer, V_MAIN)
          && ai_handicap(pplayer, H_FOG)) {
        continue;
      }
      /* Prefer big cities on other continents */
      val = city_size_get(acity)
            + (tile_continent(unit_tile(punit)) != tile_continent(ptile));
      if (val > best) {
        best = val;
	best_tile = ptile;
      }
    }
  } square_iterate_end;
Example #3
0
/**********************************************************************
  Very preliminary estimate for our intent to attack the tile (x, y).
  Used by bombers only.
**********************************************************************/
static bool dai_should_we_air_attack_tile(struct ai_type *ait,
                                          struct unit *punit, struct tile *ptile)
{
  struct city *acity = tile_city(ptile);

  /* For a virtual unit (punit->id == 0), all targets are good */
  /* TODO: There is a danger of producing too many units that will not 
   * attack anything.  Production should not happen if there is an idle 
   * unit of the same type nearby */
  if (acity && punit->id != 0
      && def_ai_city_data(acity, ait)->invasion.occupy == 0
      && !unit_can_take_over(punit)) {
    /* No units capable of occupying are invading */
    log_debug("Don't want to attack %s, although we could",
              city_name(acity));
    return FALSE;
  }

  return TRUE;
}