/* * Copyright (c) 2008 Tom Parker <thpr@users.sourceforge.net> * * 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 pcgen.cdom.base.ChooseDriver; import pcgen.cdom.base.ChooseInformation; import pcgen.cdom.base.ChooseSelectionActor; import pcgen.cdom.base.ConcretePrereqObject; import pcgen.cdom.base.Constants; import pcgen.cdom.base.QualifyingObject; import pcgen.cdom.content.CNAbilityFactory; import pcgen.cdom.enumeration.Nature; import pcgen.cdom.enumeration.ObjectKey; import pcgen.cdom.reference.CDOMSingleRef; import pcgen.core.Ability; import pcgen.core.AbilityCategory; import pcgen.core.PlayerCharacter; import pcgen.persistence.PersistenceLayerException; /** * An AbilitySelection represents a "resolved" Ability, Nature and any choice * associated with that Ability. * * This is generally used as the storage container when a selection has been * made from a token like ADD:FEAT * * @param <T> The type of object that this AbilityTargetSelector can select */ public class AbilityTargetSelector<T> extends ConcretePrereqObject implements QualifyingObject, ChooseSelectionActor<T> { private final String source; private final CDOMSingleRef<AbilityCategory> category; /** * The Ability that this AbilitySelection represents */ private final CDOMSingleRef<Ability> ability; /** * The Nature of the Ability as it should be applied to a PlayerCharacter */ private final Nature nature; /** * Creates a new AbilitySelection for the given Ability. The given Ability * must be a MULT:NO Ability or this constructor will throw an exception. * * @param abil * The Ability which this AbilitySelection will contain * @param nat * The Nature of the given Ability as it should be applied to a * PlayerCharacter */ public AbilityTargetSelector(String token, CDOMSingleRef<AbilityCategory> cat, CDOMSingleRef<Ability> abil, Nature nat) { category = cat; ability = abil; nature = nat; source = token; } /** * Returns the key for the Ability in this AbilitySelection. * * @return The key for the Ability in this AbilitySelection. */ public String getAbilityKey() { return ability.get().getKeyName(); } /** * Returns the Category for the Ability in this AbilitySelection. * * @return The Category for the Ability in this AbilitySelection. */ public CDOMSingleRef<AbilityCategory> getAbilityCategory() { return category; } /** * Returns the "full" Key required to fully resolve both the Ability and the * selection for this AbilitySelection. The choice is encoded in parenthesis * after the ability key. * * Note: This is primarily used for compatibility with "old" (5.x) style * core objects and generally use of this method is discouraged. * * @return The "full" Key required to fully resolve both the Ability and the * selection for this AbilitySelection. */ public String getFullAbilityKey() { StringBuilder sb = new StringBuilder(50); sb.append(getAbilityKey()); sb.append('('); sb.append(Constants.LST_PERCENT_LIST); sb.append(')'); return sb.toString(); } /** * Returns a String representation of this AbilitySelection. The choice is * encoded in parenthesis after the Ability's name. * * Note: Since this does not depend on the key of the underlying Ability, it * is an unreliable method to persistently store information about this * AbilitySelection. If persistent storage is required, you should be using * getPersistentFormat() * * @return A String representation of this AbilitySelection. */ @Override public String toString() { StringBuilder sb = new StringBuilder(50); sb.append(ability.get().getDisplayName()); sb.append('('); sb.append(Constants.LST_PERCENT_LIST); sb.append(')'); return sb.toString(); } /** * Returns the Nature of the Ability as it should be applied to a * PlayerCharacter * * @return The Nature of the Ability as it should be applied to a * PlayerCharacter */ public Nature getNature() { return nature; } /** * Returns the Ability that this AbilitySelection represents * * @return The Ability that this AbilitySelection represents */ public Ability getAbility() { return ability.get(); } @Override public void applyChoice(ChooseDriver obj, T choice, PlayerCharacter pc) { Ability ab = ability.get(); ChooseInformation ci = ab.get(ObjectKey.CHOOSE_INFO); detailedApply(obj, ci, choice, pc); } private void detailedApply(ChooseDriver obj, ChooseInformation<T> ci, T choice, PlayerCharacter pc) { String string = ci.encodeChoice(choice); CNAbilitySelection appliedSelection = new CNAbilitySelection( CNAbilityFactory.getCNAbility(category.get(), nature, ability.get()), string); appliedSelection.addAllPrerequisites(getPrerequisiteList()); pc.addAbility(appliedSelection, obj, this); } @Override public String getLstFormat() throws PersistenceLayerException { return ability.getLSTformat(false); } @Override public String getSource() { return source; } @Override public void removeChoice(ChooseDriver obj, T choice, PlayerCharacter pc) { Ability ab = ability.get(); ChooseInformation ci = ab.get(ObjectKey.CHOOSE_INFO); detailedRemove(obj, ci, choice, pc); } private void detailedRemove(ChooseDriver obj, ChooseInformation<T> ci, T choice, PlayerCharacter pc) { String string = ci.encodeChoice(choice); CNAbilitySelection appliedSelection = new CNAbilitySelection( CNAbilityFactory.getCNAbility(category.get(), nature, ability.get()), string); pc.removeAbility(appliedSelection, obj, this); } @Override public int hashCode() { return ability.hashCode(); } @Override public boolean equals(Object o) { if (o instanceof AbilityTargetSelector) { AbilityTargetSelector<?> other = (AbilityTargetSelector<?>) o; return source.equals(other.source) && category.equals(other.category) && ability.equals(other.ability) && nature.equals(other.nature); } return false; } @Override public Class<T> getChoiceClass() { return (Class<T>) ability.get().get(ObjectKey.CHOOSE_INFO) .getClassIdentity().getChoiceClass(); } }