From: <th...@us...> - 2008-10-14 22:41:54
|
Revision: 8075 http://pcgen.svn.sourceforge.net/pcgen/?rev=8075&view=rev Author: thpr Date: 2008-10-14 22:41:43 +0000 (Tue, 14 Oct 2008) Log Message: ----------- CONTAINS token rebuild Modified Paths: -------------- Trunk/pcgen/code/src/java/pcgen/cdom/base/Constants.java Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/IntegerKey.java Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/ListKey.java Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/ObjectKey.java Trunk/pcgen/code/src/java/pcgen/core/Equipment.java Trunk/pcgen/code/src/java/plugin/lsttokens/equipment/ContainsToken.java Added Paths: ----------- Trunk/pcgen/code/src/java/pcgen/cdom/helper/Capacity.java Modified: Trunk/pcgen/code/src/java/pcgen/cdom/base/Constants.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/cdom/base/Constants.java 2008-10-14 22:01:10 UTC (rev 8074) +++ Trunk/pcgen/code/src/java/pcgen/cdom/base/Constants.java 2008-10-14 22:41:43 UTC (rev 8075) @@ -315,5 +315,6 @@ String LST_CHOOSE = "CHOOSE:"; String LST_ADDCHOICE = "ADDCHOICE:"; char CHAR_ASTERISK = '*'; + char PERCENT = '%'; public static final int NO_LEVEL_LIMIT = -1; } Modified: Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/IntegerKey.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/IntegerKey.java 2008-10-14 22:01:10 UTC (rev 8074) +++ Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/IntegerKey.java 2008-10-14 22:41:43 UTC (rev 8075) @@ -136,6 +136,8 @@ public static final IntegerKey UMULT = getConstant("UMULT"); + public static final IntegerKey CONTAINER_REDUCE_WEIGHT = getConstant("CONTAINER_REDUCE_WEIGHT"); + /* * TODO Okay, this is a hack. This should probably be a FormulaKey rather * than an IntegerKey in order to properly handle this strange delegation. Modified: Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/ListKey.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/ListKey.java 2008-10-14 22:01:10 UTC (rev 8074) +++ Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/ListKey.java 2008-10-14 22:41:43 UTC (rev 8075) @@ -39,6 +39,7 @@ import pcgen.cdom.content.LevelCommandFactory; import pcgen.cdom.helper.Aspect; import pcgen.cdom.helper.AttackCycle; +import pcgen.cdom.helper.Capacity; import pcgen.cdom.helper.FollowerLimit; import pcgen.cdom.helper.PointCost; import pcgen.cdom.helper.Qualifier; @@ -244,6 +245,7 @@ public static final ListKey<CDOMReference<Ability>> SERVES_AS_ABILITY = new ListKey<CDOMReference<Ability>>(); public static final ListKey<ChooseResultActor> CHOOSE_ACTOR = new ListKey<ChooseResultActor>(); public static final ListKey<BonusObj> BONUS = new ListKey<BonusObj>(); + public static final ListKey<Capacity> CAPACITY = new ListKey<Capacity>(); private static CaseInsensitiveMap<ListKey<?>> map = null; Modified: Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/ObjectKey.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/ObjectKey.java 2008-10-14 22:01:10 UTC (rev 8074) +++ Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/ObjectKey.java 2008-10-14 22:41:43 UTC (rev 8075) @@ -40,6 +40,7 @@ import pcgen.cdom.content.LevelExchange; import pcgen.cdom.content.Modifier; import pcgen.cdom.content.SpellResistance; +import pcgen.cdom.helper.Capacity; import pcgen.cdom.list.ClassSkillList; import pcgen.cdom.list.ClassSpellList; import pcgen.cdom.list.DomainSpellList; @@ -223,6 +224,12 @@ public static final ObjectKey<SpellProhibitor> CHOICE = new ObjectKey<SpellProhibitor>(null); + public static final ObjectKey<Boolean> CONTAINER_CONSTANT_WEIGHT = new ObjectKey<Boolean>(Boolean.FALSE); + + public static final ObjectKey<BigDecimal> CONTAINER_WEIGHT_CAPACITY = new ObjectKey<BigDecimal>(null); + + public static final ObjectKey<Capacity> TOTAL_CAPACITY = new ObjectKey<Capacity>(null); + public static final ObjectKey<SizeAdjustment> BASESIZE; public static final ObjectKey<SizeAdjustment> SIZE; Added: Trunk/pcgen/code/src/java/pcgen/cdom/helper/Capacity.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/cdom/helper/Capacity.java (rev 0) +++ Trunk/pcgen/code/src/java/pcgen/cdom/helper/Capacity.java 2008-10-14 22:41:43 UTC (rev 8075) @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2007 Tom Parker <th...@us...> + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ +package pcgen.cdom.helper; + +import java.math.BigDecimal; + +public class Capacity +{ + + public static BigDecimal UNLIMITED = new BigDecimal(-1); + /* + * CONSIDER Need to flesh out how this works; depends on how Capacity + * interacts with the core... - Tom Parker 3/1/07 + */ + public static final Capacity ANY = new Capacity(null, UNLIMITED); + + private final String type; + + private final BigDecimal limit; + + public Capacity(String typ, BigDecimal cap) + { + type = typ; + limit = cap; + } + + public BigDecimal getCapacity() + { + return limit; + } + + public String getType() + { + return type; + } + + public static Capacity getTotalCapacity(BigDecimal d) + { + return new Capacity(null, d); + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append("Capacity: "); + sb.append(type == null ? "Total" : type); + sb.append('='); + sb.append(UNLIMITED.equals(limit) ? "UNLIMITED" : limit); + return sb.toString(); + } + + @Override + public int hashCode() + { + return type == null ? 0 : type.hashCode() ^ limit.hashCode(); + } + + @Override + public boolean equals(Object o) + { + if (o instanceof Capacity) + { + Capacity other = (Capacity) o; + if (type == null) + { + if (other.type != null) + { + return false; + } + } + else + { + if (!type.equals(other.type)) + { + return false; + } + } + return limit.equals(other.limit); + } + return false; + } +} Modified: Trunk/pcgen/code/src/java/pcgen/core/Equipment.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/core/Equipment.java 2008-10-14 22:01:10 UTC (rev 8074) +++ Trunk/pcgen/code/src/java/pcgen/core/Equipment.java 2008-10-14 22:41:43 UTC (rev 8075) @@ -54,6 +54,7 @@ import pcgen.cdom.enumeration.ListKey; import pcgen.cdom.enumeration.ObjectKey; import pcgen.cdom.enumeration.StringKey; +import pcgen.cdom.helper.Capacity; import pcgen.cdom.inst.EquipmentHead; import pcgen.cdom.modifier.ChangeArmorType; import pcgen.cdom.reference.CDOMDirectSingleRef; @@ -93,8 +94,6 @@ { private static final long serialVersionUID = 1; - private static final int UNLIMITED_CAPACITY = -1; - private static final String EQMOD_WEIGHT = "_WEIGHTADD"; private static final String EQMOD_DAMAGE = "_DAMAGE"; @@ -200,21 +199,11 @@ private int numberEquipped; - private Float containerWeightCapacity = (float) 0; - - private Integer containerReduceWeight = 0; - - private boolean containerConstantWeight; - - private boolean d_acceptsChildren; - private boolean isOnlyNaturalWeapon; - private Map<String, Float> d_acceptsTypes = new HashMap<String, Float>(); - private Map<String, Float> d_childTypes = new HashMap<String, Float>(); - private String containerCapacityString = ""; + private String containerCapacityString = null; private String containerContentsString = ""; @@ -2185,7 +2174,7 @@ * @return true if the Equipment can take children. */ public boolean acceptsChildren() { - return d_acceptsChildren; + return get(ObjectKey.CONTAINER_WEIGHT_CAPACITY) != null; } /** @@ -2725,19 +2714,9 @@ eq.numberEquipped = numberEquipped; eq.qty = qty; eq.outputIndex = outputIndex; - eq.containerWeightCapacity = containerWeightCapacity; - eq.containerReduceWeight = containerReduceWeight; - eq.d_acceptsChildren = d_acceptsChildren; - eq.d_acceptsTypes = new HashMap<String, Float>(d_acceptsTypes); - - eq.containerConstantWeight = containerConstantWeight; - eq.d_childTypes = new HashMap<String, Float>(d_childTypes); - eq.containerContentsString = containerContentsString; - eq.containerCapacityString = containerCapacityString; - eq.d_containedEquipment = new ArrayList<Equipment>(d_containedEquipment); @@ -3346,7 +3325,8 @@ // // Adjust the capacity of the container (if it is one) // - if (containerCapacityString.length() > 0) + BigDecimal weightCap = get(ObjectKey.CONTAINER_WEIGHT_CAPACITY); + if (weightCap != null) { double mult = 1.0; @@ -3357,23 +3337,26 @@ eq.typeList(), 1.0); } - if (containerWeightCapacity.intValue() != -1) + BigDecimal multbd = new BigDecimal(mult); + if (!Capacity.UNLIMITED.equals(weightCap)) { - containerWeightCapacity = - new Float(eq.containerWeightCapacity.doubleValue() - * mult); + // CONSIDER ICK, ICK, direct access bad + put(ObjectKey.CONTAINER_WEIGHT_CAPACITY, weightCap + .multiply(multbd)); } - if (getAcceptsTypeCount() > 0) + List<Capacity> capacity = removeListFor(ListKey.CAPACITY); + if (capacity != null) { - for (String aString : eq.d_acceptsTypes.keySet()) + for (Capacity cap : capacity) { - Float aWeight = eq.getAcceptsType(aString); - - if (aWeight.intValue() != -1) + BigDecimal content = cap.getCapacity(); + if (!Capacity.UNLIMITED.equals(content)) { - aWeight = new Float(aWeight.doubleValue() * mult); - setAcceptsType(aString, aWeight); + content = content.multiply(multbd); } + // CONSIDER ICK, ICK, direct access bad + addToListFor(ListKey.CAPACITY, new Capacity(cap + .getType(), content)); } } @@ -3513,51 +3496,11 @@ } /** - * Update the container contents String - */ - public void updateContainerContentsString() { - containerContentsString = ""; - - final StringBuffer tempStringBuffer = new StringBuffer( - getChildCount() * 20); - - // Make sure there's no bug here. - if (acceptsChildren() - && (getBaseContainedWeight(true) >= 0.0f)) { - tempStringBuffer.append( - Globals.getGameModeUnitSet().displayWeightInUnitSet( - getBaseContainedWeight(true).doubleValue())) - .append(Globals.getGameModeUnitSet().getWeightUnit()); - } else { - // have to put something - tempStringBuffer.append("0.0 "); - tempStringBuffer.append(Globals.getGameModeUnitSet() - .getWeightUnit()); - } - - for (int e = 0; e < getChildCount(); ++e) { - final Equipment anEquip = (Equipment) getChild(e); - - if (anEquip.getQty() > 0.0f) { - tempStringBuffer.append(", "); - tempStringBuffer.append(BigDecimalHelper.trimZeros(anEquip - .getQty().toString())); - tempStringBuffer.append(" "); - tempStringBuffer.append(anEquip); - } - } - - containerContentsString = tempStringBuffer.toString(); - } - - /** * Updates the containerContentsString from children of this item * * @param pc The PC carrying the item */ public void updateContainerContentsString(final PlayerCharacter pc) { - containerContentsString = ""; - final StringBuffer tempStringBuffer = new StringBuffer( getChildCount() * 20); @@ -3665,45 +3608,6 @@ return true; } - /** - * For a container, sets the types that will be accepted, and how many - * of them the item can hold - * - * @param parameter - * the Type to accept - * @param acceptsType - * How many it will accept - */ - private void setAcceptsType( - final String parameter, - final Float acceptsType) { - - d_acceptsTypes.put(parameter.toUpperCase(), acceptsType); - } - - /** - * If this item is a container that accepts the Type of equipment - * then the capacity for that type of equipment will be returned. - * If the object is not a container capable of holding Equipment of - * type aType, then null is returned. - * - * @param aType the Type of equipment - * - * @return The acceptsTypes value - */ - private Float getAcceptsType(final String aType) { - return d_acceptsTypes.get(aType.toUpperCase()); - } - - /** - * Gets the number of accepted types - * - * @return The number of distinct types - */ - private int getAcceptsTypeCount() { - return d_acceptsTypes.size(); - } - private int getAltTypeCount() { if (altTypeList == null) { return 0; @@ -4138,7 +4042,14 @@ * @return The acceptsTypes value */ private boolean acceptsType(final String aString) { - return d_acceptsTypes.containsKey(aString.toUpperCase()); + for (Capacity cap : getSafeListFor(ListKey.CAPACITY)) + { + if (cap.getType().equalsIgnoreCase(aString)) + { + return true; + } + } + return false; } private void addAltType(final String type) { @@ -4263,8 +4174,10 @@ final PlayerCharacter aPC, final Float aFloat) { - return containerWeightCapacity.intValue() == -1 || - (aFloat + getContainedWeight(aPC)) <= containerWeightCapacity; + BigDecimal weightCap = get(ObjectKey.CONTAINER_WEIGHT_CAPACITY); + return weightCap != null + && (Capacity.UNLIMITED.equals(weightCap) || + (aFloat + getContainedWeight(aPC)) <= weightCap.doubleValue()); } /** @@ -4280,13 +4193,8 @@ final SortedSet<String> aTypeList, final Float aQuant) { - if (acceptsType("Any")) { - if (getAcceptsType("Any").intValue() == -1) { - return true; - } - } - - return !("".equals(pickChildType(aTypeList, aQuant))); + return Capacity.ANY.equals(get(ObjectKey.TOTAL_CAPACITY)) + || !("".equals(pickChildType(aTypeList, aQuant))); } private List<EquipmentModifier> cloneEqModList(final boolean primary) { @@ -4460,41 +4368,47 @@ final SortedSet<String> aTypeList, final Float quantToAdd) { - Float acceptsType = getAcceptsType("TOTAL"); - - // Sanity check - if (acceptsType == null) { - acceptsType = 0f; - } - + Capacity totalCap = get(ObjectKey.TOTAL_CAPACITY); + BigDecimal capValue = totalCap.getCapacity(); + if (getChildType("Total") == null) { setChildType("Total", 0f); } String canContain = ""; - if ((getChildType("Total") + quantToAdd) <= acceptsType) { - for (String aType : aTypeList) { - if (!"".equals(canContain)) { - break; - } - if (acceptsType(aType)) { - if (containsChildType(aType) && - ((getChildType(aType) + quantToAdd) <= getAcceptsType(aType))) { - canContain = aType; - } else if (quantToAdd <= getAcceptsType(aType)) { - canContain = aType; + if ((getChildType("Total") + quantToAdd) <= capValue.doubleValue()) { + boolean anyContain = false; + float childType = containsChildType("Any") ? getChildType("Any") : 0.0f; + CAPFOR: for (Capacity c : getSafeListFor(ListKey.CAPACITY)) + { + String capType = c.getType(); + double val = c.getCapacity().doubleValue(); + for (String aType : aTypeList) { + if (capType.equalsIgnoreCase(aType)) + { + if (containsChildType(aType) + && ((getChildType(aType) + quantToAdd) <= val) + || quantToAdd <= val) + { + canContain = aType; + break CAPFOR; + } } + else if ("Any".equalsIgnoreCase(capType)) + { + if ((childType + quantToAdd) <= val) { + anyContain = true; + } + } } } + - if (("".equals(canContain)) && acceptsType("Any")) { + if (("".equals(canContain)) && anyContain) { if (!containsChildType("Any")) { setChildType("Any", (float) 0); } - - if ((getChildType("Any") + quantToAdd) <= getAcceptsType("Any")) { - canContain = "Any"; - } + canContain = "Any"; } } @@ -4781,27 +4695,31 @@ final StringBuffer tempStringBuffer = new StringBuffer(); boolean comma = false; - if (containerWeightCapacity.intValue() != -1) { - tempStringBuffer.append(containerWeightCapacity).append(' ') + BigDecimal weightCap = get(ObjectKey.CONTAINER_WEIGHT_CAPACITY); + if (weightCap != null && !Capacity.UNLIMITED.equals(weightCap)) + { + tempStringBuffer.append(weightCap).append(' ') .append(Globals.getGameModeUnitSet().getWeightUnit()); comma = true; } - if (getAcceptsTypeCount() > 0) { - for (String aString : d_acceptsTypes.keySet()) { + List<Capacity> capacity = getListFor(ListKey.CAPACITY); + if (capacity != null) { + for (Capacity c : capacity) { if (comma) { tempStringBuffer.append(", "); comma = false; } - - if (getAcceptsType(aString).intValue() != -1) { - tempStringBuffer.append( - getAcceptsType(aString).floatValue()).append(' '); - tempStringBuffer.append(aString); + + BigDecimal capValue = c.getCapacity(); + if (!Capacity.UNLIMITED.equals(capValue)) + { + tempStringBuffer.append(capValue).append(' '); + tempStringBuffer.append(c.getType()); comma = true; - } else if (!"TOTAL".equals(aString)) { + } else if (c.getType() != null) { comma = true; - tempStringBuffer.append(aString); + tempStringBuffer.append(c.getType()); } } } @@ -5552,7 +5470,7 @@ Float total = (float) 0; - if ((containerConstantWeight && !effective) || (getChildCount() == 0)) { + if ((getSafe(ObjectKey.CONTAINER_CONSTANT_WEIGHT) && !effective) || (getChildCount() == 0)) { return total; } @@ -5569,8 +5487,9 @@ } } - if (containerReduceWeight > 0) { - total *= (containerReduceWeight.floatValue() / 100); + Integer crw = get(IntegerKey.CONTAINER_REDUCE_WEIGHT); + if (crw != null && crw != 0) { + total *= (crw.floatValue() / 100); } return total; @@ -5590,7 +5509,7 @@ final boolean effective) { Float total = 0f; - if ((containerConstantWeight && !effective) || (getChildCount() == 0)) { + if ((getSafe(ObjectKey.CONTAINER_CONSTANT_WEIGHT) && !effective) || (getChildCount() == 0)) { return total; } @@ -5610,8 +5529,9 @@ } } - if (containerReduceWeight > 0) { - total *= (containerReduceWeight.floatValue() / 100); + Integer crw = get(IntegerKey.CONTAINER_REDUCE_WEIGHT); + if (crw != null && crw != 0) { + total *= (crw.floatValue() / 100); } return total; @@ -5677,6 +5597,10 @@ * @return The containerContentsString value */ public String getContainerContentsString() { + if (containerContentsString == null) + { + updateContainerContentsString(null); + } return containerContentsString; } @@ -5707,134 +5631,15 @@ // --------------------------- /** - * Set the container properties of this item - * - * @param tokenString The list of types and quantities that this item - * may contain - */ - public void setContainer(final String tokenString) { - setContainer(null, tokenString); - } - - /** - * Sets the container attribute of the Equipment object - * - * @param pc The PC that has the Equipment - * - * @param tokenString - * The new container value - */ - public void setContainer(final PlayerCharacter pc, final String tokenString) { - - d_acceptsChildren = true; - - final StringTokenizer aTok = new StringTokenizer(tokenString, "|"); - - if (aTok.hasMoreTokens()) { - String bString = aTok.nextToken(); - - if ((bString != null) && (bString.charAt(0) == '*')) { - containerConstantWeight = true; - bString = bString.substring(1); - } - - if ((bString != null) && (bString.indexOf('%') > 0)) { - final int pos = bString.indexOf('%'); - final String redString = bString.substring(0, pos); - bString = bString.substring(pos + 1); - - try { - containerReduceWeight = Integer.valueOf(redString); - } catch (NumberFormatException ex) { - Logging.errorPrint("Error in CONTAINS line: " + tokenString); - containerReduceWeight = 0; - } - } - - try { - containerWeightCapacity = new Float(bString); - if (containerWeightCapacity < 0) - { - Logging.deprecationPrint(getKeyName() - + " Weight Capacity must be >= 0: " + bString - + "\n use 'UNLIM' (not -1) for unlimited Capacity"); - } - } catch (NumberFormatException ex) { - if (!"UNLIM".equals(bString)) - { - Logging.log(Logging.LST_ERROR, "Error in CONTAINS line: " + tokenString - + "\n" + " " + bString - + " was not a number or 'UNLIM'"); - } - containerWeightCapacity = (float) UNLIMITED_CAPACITY; - } - } else { - containerWeightCapacity = (float) UNLIMITED_CAPACITY; - } - - boolean limited = true; - if (!aTok.hasMoreTokens()) { - limited = false; - setAcceptsType("Any", (float) UNLIMITED_CAPACITY); - } - - Float aFloat = 0f; - while (aTok.hasMoreTokens()) { - final StringTokenizer typeTok = - new StringTokenizer(aTok.nextToken(), "="); - String itemType = typeTok.nextToken(); - - Float itemNumber; - if (typeTok.hasMoreTokens()) { - String itemCount = typeTok.nextToken(); - if ("UNLIM".equals(itemCount)) - { - limited = false; - itemNumber = (float) UNLIMITED_CAPACITY; - } - else - { - itemNumber = new Float(itemCount); - - if (itemNumber < 0) - { - Logging.errorPrint(getKeyName() + " Item Count for " - + itemType + " must be > 0: " + itemCount - + "\n use 'UNLIM' (not -1) for unlimited Count"); - } - - if (limited) { - aFloat += itemNumber; - } - } - } else { - limited = false; - itemNumber = (float) UNLIMITED_CAPACITY; - } - - if (!"Any".equals(itemType) && !"Total".equals(itemType)) { - setAcceptsType(itemType, itemNumber); - } else { - setAcceptsType(itemType, itemNumber); - } - } - - if (!acceptsType("Total")) { - Float f = limited ? aFloat : (float) UNLIMITED_CAPACITY; - - setAcceptsType("Total", f); - } - - updateContainerCapacityString(); - updateContainerContentsString(pc); - } - - /** * Gets the containerCapacityString attribute of the Equipment object * * @return The containerCapacityString value */ public String getContainerCapacityString() { + if (containerCapacityString == null) + { + updateContainerCapacityString(); + } return containerCapacityString; } Modified: Trunk/pcgen/code/src/java/plugin/lsttokens/equipment/ContainsToken.java =================================================================== --- Trunk/pcgen/code/src/java/plugin/lsttokens/equipment/ContainsToken.java 2008-10-14 22:01:10 UTC (rev 8074) +++ Trunk/pcgen/code/src/java/plugin/lsttokens/equipment/ContainsToken.java 2008-10-14 22:41:43 UTC (rev 8075) @@ -1,22 +1,304 @@ package plugin.lsttokens.equipment; +import java.math.BigDecimal; +import java.util.Collection; +import java.util.StringTokenizer; + +import pcgen.cdom.base.Constants; +import pcgen.cdom.enumeration.IntegerKey; +import pcgen.cdom.enumeration.ListKey; +import pcgen.cdom.enumeration.ObjectKey; +import pcgen.cdom.helper.Capacity; import pcgen.core.Equipment; -import pcgen.persistence.lst.EquipmentLstToken; +import pcgen.rules.context.Changes; +import pcgen.rules.context.LoadContext; +import pcgen.rules.persistence.token.AbstractToken; +import pcgen.rules.persistence.token.CDOMPrimaryToken; +import pcgen.util.BigDecimalHelper; +import pcgen.util.Logging; /** - * Deals with CONTAINS token + * Deals with CONTAINS token */ -public class ContainsToken implements EquipmentLstToken +public class ContainsToken extends AbstractToken implements + CDOMPrimaryToken<Equipment> { + @Override public String getTokenName() { return "CONTAINS"; } - public boolean parse(Equipment eq, String value) + public boolean parse(LoadContext context, Equipment eq, String value) { - eq.setContainer(value); + if (isEmpty(value) || hasIllegalSeparator('|', value)) + { + return false; + } + + StringTokenizer pipeTok = new StringTokenizer(value, Constants.PIPE); + + /* + * TODO I believe this needs to clear the List and if it already + * contains something, then should it provide an informational message? + */ + String weightCapacity = pipeTok.nextToken(); + + boolean hadAsterisk = false; + if (weightCapacity.charAt(0) == Constants.CHAR_ASTERISK) + { + hadAsterisk = true; + context.getObjectContext().put(eq, + ObjectKey.CONTAINER_CONSTANT_WEIGHT, Boolean.TRUE); + weightCapacity = weightCapacity.substring(1); + } + + int percentLoc = weightCapacity.indexOf(Constants.PERCENT); + if (percentLoc != weightCapacity.lastIndexOf(Constants.PERCENT)) + { + Logging.addParseMessage(Logging.LST_ERROR, + "Cannot have two weight reduction " + + "characters (indicated by %): " + value); + return false; + } + if (percentLoc != -1) + { + if (hadAsterisk) + { + Logging.addParseMessage(Logging.LST_ERROR, + "Cannot have Constant Weight (indicated by *) " + + "and weight reduction (indicated by %): " + + value); + return false; + } + String redString = weightCapacity.substring(0, percentLoc); + weightCapacity = weightCapacity.substring(percentLoc + 1); + + try + { + context.getObjectContext().put(eq, + IntegerKey.CONTAINER_REDUCE_WEIGHT, + Integer.valueOf(redString)); + } + catch (NumberFormatException ex) + { + Logging.addParseMessage(Logging.LST_ERROR, + "Weight Reduction (indicated by %) must be an integer: " + + value); + return false; + } + } + + BigDecimal weightCap; + if ("UNLIM".equals(weightCapacity)) + { + weightCap = Capacity.UNLIMITED; + } + else + { + try + { + weightCap = BigDecimalHelper.trimBigDecimal(new BigDecimal( + weightCapacity)); + if (BigDecimal.ZERO.compareTo(weightCap) > 0) + { + Logging + .addParseMessage( + Logging.LST_ERROR, + "Weight Capacity must be >= 0: " + + weightCapacity + + "\n Use 'UNLIM' (not -1) for unlimited Count"); + return false; + } + } + catch (NumberFormatException ex) + { + Logging.addParseMessage(Logging.LST_ERROR, + "Weight Capacity must be 'UNLIM or a number >= 0: " + + weightCapacity); + return false; + } + } + context.getObjectContext().put(eq, ObjectKey.CONTAINER_WEIGHT_CAPACITY, + weightCap); + + Capacity totalCap = null; + boolean limited = true; + if (!pipeTok.hasMoreTokens()) + { + limited = false; + totalCap = Capacity.ANY; + } + + BigDecimal limitedCapacity = BigDecimal.ZERO; + + while (pipeTok.hasMoreTokens()) + { + String typeString = pipeTok.nextToken(); + int equalLoc = typeString.indexOf(Constants.EQUALS); + if (equalLoc != typeString.lastIndexOf(Constants.EQUALS)) + { + return false; + } + if (equalLoc == -1) + { + limited = false; + context.getObjectContext().addToList(eq, ListKey.CAPACITY, + new Capacity(typeString, Capacity.UNLIMITED)); + } + else + { + String itemType = typeString.substring(0, equalLoc); + String itemNumString = typeString.substring(equalLoc + 1); + BigDecimal itemNumber; + if ("UNLIM".equals(itemNumString)) + { + limited = false; + itemNumber = Capacity.UNLIMITED; + } + else + { + try + { + itemNumber = BigDecimalHelper + .trimBigDecimal(new BigDecimal(itemNumString)); + } + catch (NumberFormatException ex) + { + Logging.addParseMessage(Logging.LST_ERROR, + "Item Number for " + itemType + + " must be 'UNLIM' or a number > 0: " + + itemNumString); + return false; + } + if (BigDecimal.ZERO.compareTo(itemNumber) >= 0) + { + Logging.addParseMessage(Logging.LST_ERROR, + "Cannot have negative quantity of " + itemType + + ": " + value); + return false; + } + } + if (limited) + { + limitedCapacity = limitedCapacity.add(itemNumber); + } + context.getObjectContext().addToList(eq, ListKey.CAPACITY, + new Capacity(itemType, itemNumber)); + } + } + + if (totalCap == null) + { + BigDecimal totalCapacity = limited ? limitedCapacity + : Capacity.UNLIMITED; + totalCap = Capacity.getTotalCapacity(totalCapacity); + } + + context.getObjectContext().put(eq, ObjectKey.TOTAL_CAPACITY, totalCap); return true; } + + public String[] unparse(LoadContext context, Equipment eq) + { + Changes<Capacity> changes = context.getObjectContext().getListChanges( + eq, ListKey.CAPACITY); + if (changes == null || changes.isEmpty()) + { + return null; + } + StringBuilder sb = new StringBuilder(); + + Boolean b = context.getObjectContext().getObject(eq, + ObjectKey.CONTAINER_CONSTANT_WEIGHT); + if (b != null && b.booleanValue()) + { + sb.append(Constants.CHAR_ASTERISK); + } + + Integer reducePercent = context.getObjectContext().getInteger(eq, + IntegerKey.CONTAINER_REDUCE_WEIGHT); + if (reducePercent != null) + { + sb.append(reducePercent).append(Constants.PERCENT); + } + + BigDecimal cap = context.getObjectContext().getObject(eq, + ObjectKey.CONTAINER_WEIGHT_CAPACITY); + if (cap == null) + { + // CONSIDER ERROR?? + return null; + } + if (Capacity.UNLIMITED.equals(cap)) + { + sb.append("UNLIM"); + } + else + { + sb.append(cap); + } + + Collection<Capacity> capacityList = changes.getAdded(); + if (capacityList.size() == 1) + { + for (Capacity c : capacityList) + { + if (c.getType() == null + && Capacity.UNLIMITED.equals(c.getCapacity())) + { + // Special Case: Nothing additional + return new String[] { sb.toString() }; + } + } + } + BigDecimal limitedCapacity = BigDecimal.ZERO; + boolean limited = true; + Capacity total = null; + for (Capacity c : capacityList) + { + String capType = c.getType(); + if (capType == null) + { + total = c; + } + else + { + sb.append(Constants.PIPE); + BigDecimal thisCap = c.getCapacity(); + sb.append(capType); + if (Capacity.UNLIMITED.equals(thisCap)) + { + limited = false; + } + else + { + if (limited) + { + limitedCapacity = limitedCapacity.add(thisCap); + } + sb.append(Constants.EQUALS).append(thisCap); + } + } + } + if (total == null) + { + // Error + return null; + } + if (!limitedCapacity.equals(total.getCapacity()) + && !Capacity.UNLIMITED.equals(total.getCapacity())) + { + // Need to write out total + sb.append("Total").append(Constants.EQUALS).append( + total.getCapacity()); + } + return new String[] { sb.toString() }; + } + + public Class<Equipment> getTokenClass() + { + return Equipment.class; + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |