/* * Copyright (c) Thomas Parker, 2009. * * 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.Collections; import java.util.IdentityHashMap; import java.util.Set; import pcgen.base.util.WrappedMapSet; import pcgen.cdom.base.SetFacet; import pcgen.cdom.enumeration.CharID; import pcgen.cdom.facet.base.AbstractDataFacet; import pcgen.cdom.facet.event.DataFacetChangeEvent; import pcgen.core.Equipment; import pcgen.output.publish.OutputDB; /** * EquippedEquipmentFacet is a Facet that tracks the Equipment that is Equipped * by a Player Character. * * @author Thomas Parker (thpr [at] yahoo.com) */ public class EquippedEquipmentFacet extends AbstractDataFacet<CharID, Equipment> implements SetFacet<CharID, Equipment> { private EquipmentFacet equipmentFacet; /** * Triggered ("manually") when the equipped equipment on a Player Character * has changed. Evaluates all Equipment available to the Player Character * and places the Equipped Equipment into this EquippedEquipmentFacet. * * @param id * The CharID representing the Player Character for which the * equipped Equipment should be updated */ public void reset(CharID id) { Set<Equipment> oldEquipped = (Set<Equipment>) removeCache(id); Set<Equipment> currentEquipment = equipmentFacet.getSet(id); Set<Equipment> newEquipped = new WrappedMapSet<>( IdentityHashMap.class); setCache(id, newEquipped); if (oldEquipped != null) { // Delete items that the PC no longer has at all for (Equipment e : oldEquipped) { if (!currentEquipment.contains(e)) { fireDataFacetChangeEvent(id, e, DataFacetChangeEvent.DATA_REMOVED); } } } for (Equipment e : currentEquipment) { if (e.isEquipped()) { newEquipped.add(e); // If not old, it's added if (oldEquipped == null || !oldEquipped.contains(e)) { fireDataFacetChangeEvent(id, e, DataFacetChangeEvent.DATA_ADDED); } } else { // If old, it's removed if (oldEquipped != null && oldEquipped.contains(e)) { fireDataFacetChangeEvent(id, e, DataFacetChangeEvent.DATA_REMOVED); } } } } /** * Returns a non-null copy of the Set of Equipment in this * EquippedEquipmentFacet for the Player Character represented by the given * CharID. This method returns an empty set if no objects are in this * EquippedEquipmentFacet for the Player Character identified by the given * CharID. * * This method is value-semantic in that ownership of the returned Set is * transferred to the class calling this method. Modification of the * returned Set will not modify this EquippedEquipmentFacet and modification * of this EquippedEquipmentFacet will not modify the returned Set. * Modifications to the returned Set will also not modify any future or * previous objects returned by this (or other) methods on * EquippedEquipmentFacet. If you wish to modify the information stored in * this EquippedEquipmentFacet, you must use the add*() and remove*() * methods of EquippedEquipmentFacet. * * @param id * The CharID representing the Player Character for which the * items in this EquippedEquipmentFacet should be returned * @return A non-null copy of the Set of Equipment in this * EquippedEquipmentFacet for the Player Character represented by * the given CharID */ @Override public Set<Equipment> getSet(CharID id) { Set<Equipment> set = (Set<Equipment>) getCache(id); if (set == null) { return Collections.emptySet(); } Set<Equipment> returnEquipped = new WrappedMapSet<>( IdentityHashMap.class); returnEquipped.addAll(set); return returnEquipped; } /** * Returns the count of the number of Equipment objects in this * EquippedEquipmentFacet for the Player Character represented by the given * CharID. * * @param id * The CharID representing the Player Character for which the * count of the number of items in this EquippedEquipmentFacet * should be returned * @return The count of the number of items in this EquippedEquipmentFacet * for the Player Character represented by the given CharID */ @Override public int getCount(CharID id) { Set<Equipment> set = (Set<Equipment>) getCache(id); return (set == null) ? 0 : set.size(); } public void setEquipmentFacet(EquipmentFacet equipmentFacet) { this.equipmentFacet = equipmentFacet; } /** * Copies the contents of the EquippedEquipmentFacet from one Player * Character to another Player Character, based on the given CharIDs * representing those Player Characters. * * This is a method in EquippedEquipmentFacet in order to avoid exposing the * mutable Map object to other classes. This should not be inlined, as the * Map is internal information to EquippedEquipmentFacet and should not be * exposed to other classes. * * Note also the copy is a one-time event and no references are maintained * between the Player Characters represented by the given CharIDs (meaning * once this copy takes place, any change to the EquippedEquipmentFacet of * one Player Character will only impact the Player Character where the * EquippedEquipmentFacet was changed). * * @param source * The CharID representing the Player Character from which the * information should be copied * @param copy * The CharID representing the Player Character to which the * information should be copied */ @Override public void copyContents(CharID source, CharID copy) { Set<Equipment> set = (Set<Equipment>) getCache(source); if (set != null) { Set<Equipment> newEquipped = new WrappedMapSet<>( IdentityHashMap.class); newEquipped.addAll(set); setCache(copy, newEquipped); } } /** * Remove all entries for a single character. * @param id The CharID representing the Player Character. */ public void removeAll(CharID id) { removeCache(id); } public void init() { OutputDB.register("equipment.equipped", this); } }