/** * Calculates how much of the given goods type this settlement wants and should retain. * * @param type The <code>GoodsType</code>. * @return The amount of goods wanted. */ protected int getWantedGoodsAmount(GoodsType type) { if (getUnitCount() <= 0) return 0; final Specification spec = getSpecification(); final UnitType unitType = getFirstUnit().getType(); final Role militaryRole = Role.getAvailableRoles(getOwner(), unitType, spec.getMilitaryRoles()).get(0); if (type.isMilitaryGoods()) { // Retain enough goods to fully arm. int need = 0; for (Unit u : ownedUnits) { if (u.getRole() == militaryRole) continue; List<AbstractGoods> required = u.getGoodsDifference(militaryRole, 1); need += AbstractGoods.getCount(type, required); } return need; } int consumption = getConsumptionOf(type); if (type == spec.getPrimaryFoodType()) { // Food is perishable, do not try to retain that much return Math.max(40, consumption * 3); } if (type.isTradeGoods() || type.isNewWorldLuxuryType() || type.isRefined()) { // Aim for 10 years supply, resupply is doubtful return Math.max(80, consumption * 20); } // Just keep some around return 2 * getUnitCount(); }
/** {@inheritDoc} */ @Override public boolean add(Locatable locatable) { boolean result = super.add(locatable); if (result && locatable instanceof Unit) { Unit indian = (Unit) locatable; if (indian.getHomeIndianSettlement() == null) { // Adopt homeless Indians indian.setHomeIndianSettlement(this); } } return result; }
/** {@inheritDoc} */ @Override public Unit getDefendingUnit(Unit attacker) { Unit defender = null; float defencePower = -1.0f; for (Unit nextUnit : getUnitList()) { float unitPower = attacker.getGame().getCombatModel().getDefencePower(attacker, nextUnit); if (Unit.betterDefender(defender, defencePower, nextUnit, unitPower)) { defender = nextUnit; defencePower = unitPower; } } return defender; }
/** * Gets the goods this settlement is willing to sell. * * @param limit The maximum number of goods required. * @param unit The <code>Unit</code> that is trading. * @return A list of goods to sell. */ public List<Goods> getSellGoods(int limit, Unit unit) { List<Goods> result = new ArrayList<>(); List<Goods> settlementGoods = getCompactGoods(); Collections.sort(settlementGoods, exportGoodsComparator); int count = 0; for (Goods goods : settlementGoods) { if (!willSell(goods.getType())) continue; int amount = goods.getAmount(); int retain = getWantedGoodsAmount(goods.getType()); if (retain >= amount) continue; amount -= retain; if (amount > GoodsContainer.CARGO_SIZE) { amount = GoodsContainer.CARGO_SIZE; } if (unit != null) { amount = Math.round( applyModifiers( (float) amount, getGame().getTurn(), unit.getModifiers(Modifier.TRADE_VOLUME_PENALTY))); } if (amount < TRADE_MINIMUM_SIZE) continue; result.add(new Goods(getGame(), this, goods.getType(), amount)); count++; if (count >= limit) break; } return result; }
/** {@inheritDoc} */ @Override protected void readChildren(FreeColXMLReader xr) throws XMLStreamException { // Clear containers. contactLevels.clear(); alarm.clear(); missionary = null; ownedUnits.clear(); super.readChildren(xr); // @compat 0.10.1 for (Unit u : getUnitList()) { if (u.getLocation() != this) { u.setLocationNoUpdate(this); logger.warning("Fixing unit location" + " from " + u.getLocation() + " to " + this.getId()); } } // end @compat }
/** {@inheritDoc} */ @Override protected void readChild(FreeColXMLReader xr) throws XMLStreamException { final Game game = getGame(); final String tag = xr.getLocalName(); if (ALARM_TAG.equals(tag)) { Player player = xr.findFreeColGameObject(game, PLAYER_TAG, Player.class, (Player) null, true); // @compat 0.10.5 if (getName() != null) { // Alarm used to imply contact, but only set contacted if // we also have a valid name for the settlement. setContacted(player); } // end @compat alarm.put(player, new Tension(xr.getAttribute(VALUE_TAG, 0))); xr.closeTag(ALARM_TAG); } else if (CONTACT_LEVEL_TAG.equals(tag)) { ContactLevel cl = xr.getAttribute(LEVEL_TAG, ContactLevel.class, ContactLevel.UNCONTACTED); Player player = xr.findFreeColGameObject(game, PLAYER_TAG, Player.class, (Player) null, true); contactLevels.put(player, cl); xr.closeTag(CONTACT_LEVEL_TAG); // @compat 0.10.5 } else if (IS_VISITED_TAG.equals(tag)) { Player player = xr.findFreeColGameObject(game, PLAYER_TAG, Player.class, (Player) null, true); setScouted(player); xr.closeTag(IS_VISITED_TAG); // end @compat } else if (MISSIONARY_TAG.equals(tag)) { xr.nextTag(); missionary = xr.readFreeColGameObject(game, Unit.class); missionary.setLocationNoUpdate(this); xr.closeTag(MISSIONARY_TAG); // @compat 0.10.1 } else if (OLD_UNITS_TAG.equals(tag)) { while (xr.nextTag() != XMLStreamConstants.END_ELEMENT) { super.readChild(xr); } // end @compat } else if (OWNED_UNITS_TAG.equals(tag)) { Unit unit = xr.makeFreeColGameObject(game, ID_ATTRIBUTE_TAG, Unit.class, true); addOwnedUnit(unit); xr.closeTag(OWNED_UNITS_TAG); } else { super.readChild(xr); } }
/** * Is a unit permitted to make contact with this settlement? The unit must be from a nation that * has already made contact, or in the first instance, must be arriving by land, with the * exception of trading ships. * * @param unit The <code>Unit</code> that proposes to contact this settlement. * @return True if the settlement accepts such contact. */ public boolean allowContact(Unit unit) { return unit.getOwner().hasContacted(owner) || !unit.isNaval() || unit.hasGoodsCargo(); }
/** {@inheritDoc} */ @Override protected void writeChildren(FreeColXMLWriter xw) throws XMLStreamException { super.writeChildren(xw); if (missionary != null) { xw.writeStartElement(MISSIONARY_TAG); missionary.toXML(xw); xw.writeEndElement(); } if (xw.validFor(getOwner())) { for (Player p : getSortedCopy(contactLevels.keySet())) { xw.writeStartElement(CONTACT_LEVEL_TAG); xw.writeAttribute(LEVEL_TAG, contactLevels.get(p)); xw.writeAttribute(PLAYER_TAG, p); xw.writeEndElement(); } for (Player p : getSortedCopy(alarm.keySet())) { xw.writeStartElement(ALARM_TAG); xw.writeAttribute(PLAYER_TAG, p); xw.writeAttribute(VALUE_TAG, alarm.get(p).getValue()); xw.writeEndElement(); } for (Unit unit : getSortedCopy(ownedUnits)) { xw.writeStartElement(OWNED_UNITS_TAG); xw.writeAttribute(ID_ATTRIBUTE_TAG, unit); xw.writeEndElement(); } } else { Player client = xw.getClientPlayer(); ContactLevel cl = contactLevels.get(client); if (cl != null) { xw.writeStartElement(CONTACT_LEVEL_TAG); xw.writeAttribute(LEVEL_TAG, cl); xw.writeAttribute(PLAYER_TAG, client); xw.writeEndElement(); } Tension alarm = getAlarm(client); if (alarm != null) { xw.writeStartElement(ALARM_TAG); xw.writeAttribute(PLAYER_TAG, client); xw.writeAttribute(VALUE_TAG, alarm.getValue()); xw.writeEndElement(); } } }