/* * 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.Map; import java.util.Map.Entry; import java.util.Set; import pcgen.base.util.HashMapToList; import pcgen.cdom.base.CDOMList; import pcgen.cdom.enumeration.CharID; import pcgen.cdom.facet.base.AbstractSubScopeFacet; import pcgen.cdom.list.ClassSpellList; import pcgen.cdom.list.DomainSpellList; import pcgen.core.spell.Spell; import pcgen.util.Logging; /** * AvailableSpellFacet is a Facet that tracks the Available Spells (and target * objects) that are contained in a Player Character. * * @author Thomas Parker (thpr [at] yahoo.com) */ public class AvailableSpellFacet extends AbstractSubScopeFacet<CDOMList<Spell>, Integer, Spell> { /** * Returns a non-null HashMapToList indicating the spell levels and sources * of those spell levels available to a Player Character for a given Spell. * * This may return multiple spell levels because it is possible for a spell * to be accessible to a Player Character at multiple levels since it may be * available from multiple sources. This also returns the spell lists * associated with the given level, since it is possible for a multi-class * character to have access to the same spell at different levels. By * returning the source as well as the spell levels, such scenarios can be * appropriately distinguished. * * This method is value-semantic in that ownership of the returned * HashMapToList is transferred to the class calling this method. * Modification of the returned HashMapToList will not modify this * AvailableSpellFacet and modification of this AvailableSpellFacet will not * modify the returned HashMapToList. Modifications to the returned * HashMapToList will also not modify any future or previous objects * returned by this (or other) methods on AvailableSpellFacet. If you wish * to modify the information stored in this AvailableSpellFacet, you must * use the add*() and remove*() methods of AvailableSpellFacet. * * @param id * The CharID identifying the Player Character for which the * spell levels should be returned * @param sp * The Spell for which the spell levels should be returned * @return A non-null HashMapToList indicating the spell levels and sources * of those spell levels available to a Player Character for a given * Spell. */ public HashMapToList<CDOMList<Spell>, Integer> getSpellLevelInfo( CharID id, Spell sp) { HashMapToList<CDOMList<Spell>, Integer> levelInfo = new HashMapToList<>(); Map<CDOMList<Spell>, Map<Integer, Map<Spell, Set<Object>>>> listMap = (Map<CDOMList<Spell>, Map<Integer, Map<Spell, Set<Object>>>>) getCache(id); if (listMap == null) { return levelInfo; } for (Entry<CDOMList<Spell>, Map<Integer, Map<Spell, Set<Object>>>> me : listMap .entrySet()) { CDOMList<Spell> list = me.getKey(); //Check to ensure we don't use SPELLS: if (!(list instanceof ClassSpellList) && !(list instanceof DomainSpellList)) { continue; } Map<Integer, Map<Spell, Set<Object>>> levelMap = me.getValue(); for (Map.Entry<Integer, Map<Spell, Set<Object>>> lme : levelMap .entrySet()) { Integer level = lme.getKey(); Map<Spell, Set<Object>> spellMap = lme.getValue(); if (spellMap.containsKey(sp)) { levelInfo.addToListFor(list, level); } else { for (Spell spell : spellMap.keySet()) { if (spell.getKeyName().equals(sp.getKeyName())) { if (Logging.isLoggable(Logging.INFO)) { Logging.log(Logging.INFO, "Found alternate spell of same key: " + spell + " from " + spell.getSource() + " rather than " + sp.getSource()); } levelInfo.addToListFor(list, level); } } } } } return levelInfo; } }