/* * DamageReduction.java * Copyright 2006 (C) Aaron Divinsky <boomer70@yahoo.com> * * This library 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 library 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Created on March 16, 2006 * * Current Ver: $Revision: $ */ package pcgen.cdom.content; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.StringTokenizer; import pcgen.base.formula.Formula; import pcgen.cdom.base.ConcretePrereqObject; import pcgen.cdom.base.QualifyingObject; /** * Encapsulates a single DamageReduction entity. This class encapsulates a * DamageReduction entity and provides utility methods to manipulate and combine * multiple DamageReductions together. The consensus seems to be that brevity * over clarity is preferred in the output so that is what the methods attempt * to provide. * * @author boomer70 * */ public class DamageReduction extends ConcretePrereqObject implements QualifyingObject { private final Formula theReduction; private final String theBypass; /** * Constructs a DamageReduction object. The reduction is stored as a string * to allow use of JEP formulas and variables. * * @param aReduction * The reduction to set * @param aBypass * The bypass type to set. */ public DamageReduction(final Formula aReduction, final String aBypass) { theReduction = aReduction; theBypass = aBypass; } /** * Gets the string of damage types that bypass this DR. * * @return Returns the bypass. */ public String getBypass() { return theBypass; } /** * Gets the String representation of the amount of damage this DR reduces. * * @return Returns the amount of reduction. */ public Formula getReduction() { return theReduction; } /** * Gets the actual reduction this DR will apply. If the reduction is * variable and requires the PC to process, this will return -1 * * @return Amount of damage this DR reduces */ public int getRawReductionValue() { return theReduction.isStatic() ? theReduction.resolveStatic() .intValue() : -1; } /** * Gets a list of Damage Types that bypass this DR. This is just a raw list * of types. * * @return Collection of unique types converted to lower case */ public Collection<String> getBypassList() { StringTokenizer tok = new StringTokenizer(theBypass, " "); Set<String> ret = new HashSet<>(); while (tok.hasMoreTokens()) { final String val = tok.nextToken(); if (!("or".equalsIgnoreCase(val) || "and".equalsIgnoreCase(val))) { ret.add(val.toLowerCase()); } } return Collections.unmodifiableSet(ret); } /** * Returns a String representation of this DamageReduction object. * * @return String */ @Override public String toString() { String reductionString = theReduction.toString(); int val = getRawReductionValue(); if (val < 0) { reductionString = "variable"; } return reductionString + "/" + theBypass; } /** * Tests if two DR objects are the same. The test checks that all bypasses * are present in any order and that the values are the same * * @param other * The DR to test against. * @return true if the DRs are the same. */ @Override public boolean equals(Object other) { if (!(other instanceof DamageReduction)) { return false; } Collection<String> coll1 = getBypassList(); Collection<String> coll2 = ((DamageReduction) other).getBypassList(); if (coll1.containsAll(coll2) && coll2.containsAll(coll1)) { return theReduction.equals(((DamageReduction) other).theReduction); } return false; } /** * Returns a hash code to use for this object. This method is overridden to * return the same hashcode for the same DR object. That is if * dr.equals(dr1) the hashcodes must be the same * * @return A hashcode */ @Override public int hashCode() { List<String> list = new ArrayList<>(getBypassList()); Collections.sort(list); int hash = 0; for (Iterator<String> i = list.iterator(); i.hasNext();) { hash += i.next().hashCode(); } return theReduction.hashCode() + hash; } public String getLSTformat() { StringBuilder result = new StringBuilder(); result.append(theReduction); result.append('/'); result.append(theBypass); return result.toString(); } }