/* * Copyright (c) Thomas Parker, 2010. * * 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.facet; import java.util.ArrayList; import java.util.Collection; import java.util.IdentityHashMap; import java.util.List; import java.util.Set; import pcgen.base.util.WrappedMapSet; import pcgen.cdom.enumeration.CharID; import pcgen.cdom.facet.base.AbstractListFacet; import pcgen.cdom.helper.CNAbilitySelection; import pcgen.util.Logging; /** * ConditionallyGrantedAbilityFacet is a DataFacet that contains information * about Ability objects that are contained in a Player Character because the * Player Character did pass prerequisites for the conditional Ability. * * @author Thomas Parker (thpr [at] yahoo.com) */ public class ConditionallyGrantedAbilityFacet extends AbstractListFacet<CharID, CNAbilitySelection> { private ConditionalAbilityFacet conditionalAbilityFacet; /** Best guess of the current recursion level for debugging purposes only.*/ private static int depth = 0; /** * Performs a global update of conditionally granted Abilities for a Player * Character. * * @param id * The CharID identifying the Player Character for which a global * update of conditionally granted Abilities should be performed. */ public void update(CharID id) { depth++; Collection<CNAbilitySelection> current = getSet(id); Collection<CNAbilitySelection> qualified = conditionalAbilityFacet .getQualifiedSet(id); List<CNAbilitySelection> toRemove = new ArrayList<>( current); toRemove.removeAll(qualified); List<CNAbilitySelection> toAdd = new ArrayList<>( qualified); toAdd.removeAll(current); if (!toAdd.isEmpty() || !toRemove.isEmpty()) { if (Logging.isDebugMode()) { Logging.debugPrint("CGAF at depth " + depth + " removing " + toRemove + " adding " + toAdd); } } for (CNAbilitySelection cas : toRemove) { // Things could have changed, so we make sure if (!conditionalAbilityFacet.isQualified(id, cas) && contains(id, cas)) { if (Logging.isDebugMode()) { Logging.debugPrint("CGAF at depth " + depth + " removing " + cas); } remove(id, cas); } } for (CNAbilitySelection cas : toAdd) { // Things could have changed, so we make sure if (conditionalAbilityFacet.isQualified(id, cas) && !contains(id, cas)) { if (Logging.isDebugMode()) { Logging.debugPrint("CGAF at depth " + depth + " adding " + cas); } add(id, cas); } } if (!toAdd.isEmpty() || !toRemove.isEmpty()) { if (Logging.isDebugMode()) { Logging.debugPrint("CGAF at depth " + depth + " completed."); } } depth--; } /** * Overrides the default behavior of AbstractListFacet, since we need to * ensure we are storing the conditionally granted abilities by their * identity (Ability has old behavior in .equals and Abilities are still * cloned) * * @see pcgen.cdom.facet.base.AbstractListFacet#getComponentSet() */ @Override protected Set<CNAbilitySelection> getComponentSet() { return new WrappedMapSet<>( IdentityHashMap.class); } public void setConditionalAbilityFacet( ConditionalAbilityFacet conditionalAbilityFacet) { this.conditionalAbilityFacet = conditionalAbilityFacet; } }