/** * 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; }
/** {@inheritDoc} */ @Override public Mission doMission(LogBuilder lb) { lb.add(tag); String reason = invalidReason(); if (isTargetReason(reason)) { return retargetMission(reason, lb); } else if (reason != null) { return lbFail(lb, false, reason); } for (; ; ) { // Go to the target. final Unit unit = getUnit(); Unit.MoveType mt = travelToTarget(getTarget(), CostDeciders.avoidSettlementsAndBlockingUnits(), lb); switch (mt) { case MOVE: // Arrived break; case MOVE_HIGH_SEAS: case MOVE_NO_MOVES: case MOVE_NO_REPAIR: case MOVE_ILLEGAL: return lbWait(lb); case MOVE_NO_ACCESS_EMBARK: case MOVE_NO_TILE: return this; default: return lbMove(lb, mt); } // Cash in now if: // - already in Europe // - or can never get there // - it is free to transport the treasure // - or there is no potential carrier to get the treasure to there // Otherwise, it is better to send to Europe. lbAt(lb); final AIUnit aiUnit = getAIUnit(); final Europe europe = getUnit().getOwner().getEurope(); if (unit.canCashInTreasureTrain()) { AIUnit aiCarrier = null; boolean cashin = unit.isInEurope() || europe == null || unit.getTransportFee() == 0; if (!cashin && aiUnit.getTransport() == null) { cashin = assignCarrier(lb) == null; } if (cashin) return (AIMessage.askCashInTreasureTrain(aiUnit)) ? lbDone(lb, false, "cashed in") : lbFail(lb, false, "cashin"); } return retargetMission("transport expected", lb); } }
/** * Loads all valid mods from a specified directory. * * @param directory The directory to load from. */ private static void loadModDirectory(File directory) { if (directory != null && directory.isDirectory()) { LogBuilder lb = new LogBuilder(64); lb.add("In ", directory.getPath(), " found mod:"); lb.mark(); for (File f : directory.listFiles(MOD_FILTER)) { try { FreeColModFile fcmf = new FreeColModFile(f); allMods.put(fcmf.getId(), fcmf); lb.add(" ", fcmf.getId()); } catch (IOException e) { logger.log(Level.WARNING, "Bad mod in " + f.getPath(), e); } } if (lb.grew()) lb.log(logger, Level.INFO); } }
/** {@inheritDoc} */ @Override public Mission doMission(LogBuilder lb) { lb.add(tag); String reason = invalidReason(); if (reason != null) return lbFail(lb, false, reason); final AIUnit aiUnit = getAIUnit(); final Unit unit = getUnit(); final IndianSettlement is = unit.getHomeIndianSettlement(); Direction d; while (!this.demanded) { Unit.MoveType mt = travelToTarget(getTarget(), null, lb); switch (mt) { case MOVE_HIGH_SEAS: case MOVE_NO_MOVES: case MOVE_ILLEGAL: return lbWait(lb); case MOVE_NO_REPAIR: return lbFail(lb, false, AIUNITDIED); case MOVE_NO_TILE: return this; case ATTACK_SETTLEMENT: // Arrived? d = unit.getTile().getDirection(getTarget().getTile()); if (d != null) break; // Yes, arrived at target // Fall through case ATTACK_UNIT: // Something is blocking our path Location blocker = resolveBlockage(aiUnit, getTarget()); if (blocker == null) { moveRandomly(tag, null); continue; } d = unit.getTile().getDirection(blocker.getTile()); if (AIMessage.askAttack(aiUnit, d)) { return lbAttack(lb, blocker); } continue; default: return lbMove(lb, mt); } // Load the goods. lbAt(lb); Colony colony = (Colony) getTarget(); Player enemy = colony.getOwner(); Goods goods = selectGoods(colony); GoodsType type = (goods == null) ? null : goods.getType(); int amount = (goods == null) ? 0 : goods.getAmount(); if (goods == null) { if (!enemy.checkGold(1)) { return lbDone(lb, false, "empty handed"); } amount = enemy.getGold() / 20; if (amount == 0) amount = enemy.getGold(); } this.demanded = AIMessage.askIndianDemand(aiUnit, colony, type, amount); if (this.demanded && (goods == null || hasTribute())) { if (goods == null) { return lbDone(lb, false, "accepted tribute ", amount, " gold"); } lb.add(", accepted tribute ", goods); return lbRetarget(lb); } // Consider attacking if not content. int unitTension = (is == null) ? 0 : is.getAlarm(enemy).getValue(); int tension = Math.max(unitTension, unit.getOwner().getTension(enemy).getValue()); d = unit.getTile().getDirection(colony.getTile()); if (tension >= Tension.Level.CONTENT.getLimit() && d != null) { if (AIMessage.askAttack(aiUnit, d)) lbAttack(lb, colony); } return lbDone(lb, false, "refused at ", colony); } // Take the goods home for (; ; ) { Unit.MoveType mt = travelToTarget(getTarget(), CostDeciders.avoidSettlementsAndBlockingUnits(), lb); switch (mt) { case MOVE: // Arrived break; case MOVE_HIGH_SEAS: case MOVE_NO_MOVES: case MOVE_ILLEGAL: return lbWait(lb); case MOVE_NO_REPAIR: return lbFail(lb, false, AIUNITDIED); case MOVE_NO_TILE: return this; default: return lbMove(lb, mt); } // Unload the goods lbAt(lb); GoodsContainer container = unit.getGoodsContainer(); for (Goods goods : container.getCompactGoods()) { Goods tribute = container.removeGoods(goods.getType()); is.addGoods(tribute); } return lbDone(lb, false, "unloaded tribute"); } }