private Orderable parseMove(ParseContext pc, OrderPrefix op, final String[] tokens) throws OrderException { /* 3-StP: Army St Petersburg -> Moscow. (*bounce*) 1-Smy: Army Constantinople -> Aegean Sea -> Greece. keep parsing Locations until END or a -> is reached. so we keep looking for a -> until no more are found. if we have more than one, we'll add them to a list and then add that to the order Move order. */ LinkedList pathList = new LinkedList(); int idx = op.tokenIndex; int movTokIdx = findNextMoveToken(idx, tokens); while (movTokIdx != -1) { Location loc = parseLocation(pc, idx, movTokIdx, tokens); pathList.addLast(loc.getProvince()); idx = movTokIdx + 1; movTokIdx = findNextMoveToken(idx, tokens); } // add last location final Location loc = parseLocation(pc, idx, tokens.length, tokens); pathList.addLast(loc.getProvince()); // create Move order if (pathList.size() == 1) { if (pc.isRetreatPhase()) { return pc.orderFactory.createRetreat(op.power, op.location, op.unit, loc); } else { return pc.orderFactory.createMove(op.power, op.location, op.unit, loc); } } else if (pathList.size() > 1) { if (pc.isRetreatPhase()) { throw new OrderException("Convoyed Retreat orders are not allowed. Order: " + pc.orderText); } // add source location at beginning of move list pathList.addFirst(op.location.getProvince()); final Province[] route = (Province[]) pathList.toArray(new Province[pathList.size()]); return pc.orderFactory.createMove(op.power, op.location, op.unit, loc, route); } else { // this probably will not occur.... throw new OrderException("Invalid movement path in Move order: " + pc.orderText); } } // parseMove()
@Override public boolean setLocation(StateInfo stateInfo, Location location, StringBuffer sb) { if (testLocation(stateInfo, location, sb)) { currentLocNum++; src = new Location(location.getProvince(), location.getCoast()); power = stateInfo.getPosition().getSupplyCenterOwner(location.getProvince()); // srcUnitType: already defined assert (srcUnitType != null); sb.setLength(0); sb.append(Utils.getLocalString(GUIOrder.COMPLETE, getFullName())); return true; } return false; } // setLocation()
/** * Determines if the given border allows a given action. * * <p>Please note that this uses the superclass for any passed GUIOrder object. (e.g., * dip.order.Hold for dip.gui.order.GUIHold) * * <p>GUIOrder.BORDER_INVALID is appended to the StringBuffer, if 'false' is returned. */ public static boolean checkBorder( GUIOrder guiOrder, Location location, Unit.Type unitType, Phase phase, StringBuffer sb) { Class baseClass = guiOrder.getClass().getSuperclass(); Border border = location.getProvince().getTransit(location, unitType, phase, baseClass); if (border != null) { sb.append( Utils.getLocalString( GUIOrder.BORDER_INVALID, guiOrder.getFullName(), border.getDescription())); return false; } return true; } // checkBorder()
@Override public boolean testLocation(StateInfo stateInfo, Location location, StringBuffer sb) { sb.setLength(0); if (isComplete()) { sb.append(Utils.getLocalString(GUIOrder.COMPLETE, getFullName())); return false; } Position position = stateInfo.getPosition(); Province province = location.getProvince(); if (province.hasSupplyCenter()) { Power SCOwner = position.getSupplyCenterOwner(province); // general screening, applicable to all build options // if (SCOwner == null) { sb.append(Utils.getLocalString(NOBUILD_UNOWNED_SC)); return false; } if (position.hasUnit(province)) { sb.append(Utils.getLocalString(NOBUILD_UNIT_PRESENT)); return false; } if (!stateInfo.canIssueOrder(SCOwner)) { sb.append(Utils.getLocalString(NOBUILD_SC_NOT_CONTROLLED)); return false; } // indicate if we have no builds available // Adjustment.AdjustmentInfo adjInfo = stateInfo.getAdjustmenInfoMap().get(SCOwner); if (adjInfo.getAdjustmentAmount() <= 0) { sb.append(Utils.getLocalString(NOBUILD_NO_BUILDS_AVAILABLE, SCOwner.getName())); return false; } // build-option-specific, based upon RuleOptions // RuleOptions ruleOpts = stateInfo.getRuleOptions(); if (ruleOpts.getOptionValue(RuleOptions.OPTION_BUILDS) == RuleOptions.VALUE_BUILDS_ANY_OWNED) { return checkBuildUnit(stateInfo, province, location, sb); } else if (ruleOpts.getOptionValue(RuleOptions.OPTION_BUILDS) == RuleOptions.VALUE_BUILDS_ANY_IF_HOME_OWNED) { // check if we have ONE owned home supply center before buidling // in a non-home supply center. // if (SCOwner != position.getSupplyCenterHomePower(province) && !position.hasAnOwnedHomeSC(SCOwner)) { sb.append(Utils.getLocalString(NOBUILD_NEED_ONE_OWNED_SC)); return false; // failed } // we (probably) can build here return checkBuildUnit(stateInfo, province, location, sb); } else { // build only in owned HOME supply centers // if (SCOwner == position.getSupplyCenterHomePower(province)) { // we (probably) can build here return checkBuildUnit(stateInfo, province, location, sb); } // build failure. sb.append(Utils.getLocalString(NOBUILD_NOT_OWNED_HOME_SC)); return false; } } else { sb.append(Utils.getLocalString(NOBUILD_MUST_BE_AN_OWNED_SC)); return false; } // NO return here: thus we must appropriately exit within an if/else block above. } // testLocation()