/**
   * Assign a carrier for this treasure.
   *
   * @param lb A <code>LogBuilder</code> to log to.
   * @return A suitable carrier <code>AIUnit</code>, to which this unit has been queued for
   *     transport.
   */
  private AIUnit assignCarrier(LogBuilder lb) {
    final AIUnit aiUnit = getAIUnit();
    final Unit unit = getUnit();
    final Player player = unit.getOwner();
    final Europe europe = player.getEurope();

    List<Unit> carriers = player.getCarriersForUnit(unit);
    if (carriers.isEmpty()) return null;

    // Pick the closest carrier and queue this unit.
    final Location here = unit.getLocation();
    int turns = INFINITY;
    Unit closest = null;
    for (Unit c : carriers) {
      int t = c.getTurnsToReach(here);
      if (turns > t) {
        turns = t;
        closest = c;
      }
    }
    final AIMain aiMain = getAIMain();
    TransportMission tm;
    AIUnit aiCarrier;
    if (closest != null
        && (aiCarrier = aiMain.getAIUnit(closest)) != null
        && (tm = aiCarrier.getMission(TransportMission.class)) != null) {
      setTarget(europe);
      aiUnit.changeTransport(aiCarrier);
      if (tm.forceCollection(aiUnit, lb)) {
        lb.add(" forced collection on ", aiCarrier.getUnit());
        return aiCarrier;
      }
    }
    return null;
  }
示例#2
0
  /**
   * Handle a "attack"-message.
   *
   * @param server The <code>FreeColServer</code> handling the message.
   * @param player The <code>Player</code> the message applies to.
   * @param connection The <code>Connection</code> message was received on.
   * @return An update encapsulating the attack or an error <code>Element</code> on failure.
   */
  public Element handle(FreeColServer server, Player player, Connection connection) {
    ServerPlayer serverPlayer = server.getPlayer(connection);

    Unit unit;
    try {
      unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class);
    } catch (Exception e) {
      return DOMMessage.clientError(e.getMessage());
    }

    Tile tile;
    try {
      tile = unit.getNeighbourTile(directionString);
    } catch (Exception e) {
      return DOMMessage.clientError(e.getMessage());
    }

    MoveType moveType = unit.getMoveType(tile);
    if (moveType == MoveType.ENTER_INDIAN_SETTLEMENT_WITH_SCOUT
        || moveType == MoveType.ENTER_FOREIGN_COLONY_WITH_SCOUT
        || moveType.isAttack()) {; // OK
    } else {
      return DOMMessage.clientError(
          "Illegal attack move for: "
              + unitId
              + " type: "
              + moveType
              + " from: "
              + unit.getLocation().getId()
              + " to: "
              + tile.getId());
    }

    Unit defender = tile.getDefendingUnit(unit);
    if (defender == null) {
      return DOMMessage.clientError(
          "Could not find defender"
              + " in tile: "
              + tile.getId()
              + " from: "
              + unit.getLocation().getId());
    }

    // Proceed to attack.
    return server.getInGameController().combat(serverPlayer, unit, defender, null);
  }
  /**
   * Find a suitable cash in location for this unit.
   *
   * @param aiUnit The <code>AIUnit</code> to execute this mission.
   * @param range The maximum number of moves to search.
   * @param deferOK Enables deferring to a fallback colony.
   * @return A <code>PathNode</code> to the target, or null if not found which includes the case
   *     when Europe should be preferred (because the unit can not get there by itself).
   */
  private static PathNode findTargetPath(AIUnit aiUnit, int range, boolean deferOK) {
    if (invalidAIUnitReason(aiUnit) != null) return null;
    final Unit unit = aiUnit.getUnit();
    final Location start = unit.getPathStartLocation();
    final Player player = unit.getOwner();
    final Europe europe = player.getEurope();
    final Unit carrier = unit.getCarrier();
    final CostDecider standardCd = CostDeciders.avoidSettlementsAndBlockingUnits();
    PathNode path;

    if (player.getNumberOfSettlements() <= 0 || start == null) {
      // No settlements or not on the map, so go straight to
      // Europe.  If Europe does not exist then this mission is
      // doomed.
      return (europe == null)
          ? null
          : unit.findPath(unit.getLocation(), europe, carrier, standardCd);
    }

    // Can the unit get to a cash in site?
    return unit.search(start, getGoalDecider(aiUnit, deferOK), standardCd, range, carrier);
  }
示例#4
0
  /** The constructor that will add the items to this panel. */
  public ReportLabourPanel(FreeColClient freeColClient) {
    super(freeColClient, "reportLabourAction");

    this.data = new HashMap<>();
    this.unitCount = new TypeCountMap<>();
    for (Unit unit : getMyPlayer().getUnits()) {
      UnitType type = unit.getType();
      this.unitCount.incrementCount(type, 1);
      Map<Location, Integer> unitMap = this.data.get(type);
      if (unitMap == null) {
        unitMap = new HashMap<>();
        this.data.put(type, unitMap);
      }

      Location location = unit.getLocation();
      if (location == null) {
        logger.warning("Unit has null location: " + unit);
      } else if (location.getSettlement() != null) {
        location = location.getSettlement();
      } else if (unit.isInEurope()) {
        location = getMyPlayer().getEurope();
      } else if (location.getTile() != null) {
        location = location.getTile();
      }
      Integer count = unitMap.get(location);
      if (count == null) {
        unitMap.put(location, 1);
      } else {
        unitMap.put(location, count + 1);
      }
    }

    this.colonies = freeColClient.getMySortedColonies();

    DefaultListModel<LabourUnitPanel> model = new DefaultListModel<>();
    for (UnitType unitType : getSpecification().getUnitTypeList()) {
      if (unitType.isPerson() && unitType.isAvailableTo(getMyPlayer())) {
        int count = this.unitCount.getCount(unitType);
        model.addElement(new LabourUnitPanel(unitType, count));
      }
    }
    Action selectAction =
        new AbstractAction() {
          @Override
          public void actionPerformed(ActionEvent e) {
            showDetails();
          }
        };
    Action quitAction =
        new AbstractAction() {
          @Override
          public void actionPerformed(ActionEvent e) {
            getGUI().removeFromCanvas(ReportLabourPanel.this);
          }
        };

    // Add all the components
    this.panelList = new JList<>(model);
    this.panelList.getInputMap().put(KeyStroke.getKeyStroke("ENTER"), "select");
    this.panelList.getActionMap().put("select", selectAction);
    this.panelList.getInputMap().put(KeyStroke.getKeyStroke("ESCAPE"), "quit");
    this.panelList.getActionMap().put("quit", quitAction);
    this.panelList.addMouseListener(
        new MouseAdapter() {
          @Override
          public void mouseClicked(MouseEvent e) {
            if (e.getClickCount() == 2) {
              showDetails();
            }
          }
        });
    this.panelList.setOpaque(false);
    this.panelList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    this.panelList.setLayoutOrientation(JList.HORIZONTAL_WRAP);
    this.panelList.setVisibleRowCount(-1);
    this.panelList.setCellRenderer(new LabourUnitPanelRenderer());

    this.scrollPane.setViewportView(this.panelList);
  }