/* * 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.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import pcgen.cdom.base.CDOMObject; import pcgen.cdom.enumeration.CharID; import pcgen.core.PlayerCharacter; import pcgen.core.bonus.BonusObj; import pcgen.core.bonus.BonusPair; /** * This is a transition class, designed to allow things to be taken out of * PlayerCharacter while a transition is made to a system where bonuses are * captured when items are entered into the PlayerCharacter and can be * subscribed to by facets... and is thus different than today's (5.x) core. * * Note that this does not refer to the BonusObj objects being captured and * added to the PlayerCharacter in BonusActivationFacet. This facet is focused * on the actual bonus values themselves (meaning the aggregate results of * calculations). * * @author Thomas Parker (thpr [at] yahoo.com) */ public class BonusCheckingFacet { private final PlayerCharacterTrackingFacet trackingFacet = FacetLibrary .getFacet(PlayerCharacterTrackingFacet.class); /** * Returns a specific bonus for a given Bonus type and Bonus name on the * Player Character identified by the given CharID. * * @param id * The CharID identifying the Player Character for which the * bonus of a given Bonus type and Bonus name should be returned * @param bonusType * The Bonus type for which the bonus should be returned * @param bonusName * The Bonus name for which the bonus should be returned * @return A specific bonus for a given Bonus type and Bonus name on the * Player Character identified by the given CharID */ public double getBonus(CharID id, String bonusType, String bonusName) { PlayerCharacter pc = trackingFacet.getPC(id); return pc.getTotalBonusTo(bonusType, bonusName); } /** * Calculates the bonus for the Player Character identified by the given * CharID. The Bonus is calculated based on the BonusObj objects passed in * the given map. The value in the map indicates the source object of the * BonusObj. * * This method is reference-semantic in that ownership of the Map which is * passed to this method is not transferred to this method. This method * guarantees that no modifications are made to the provided Map, and no * reference to the given Map will be retained by BonusCheckingFacet. * * @param id * The CharID of the Player Character for which the bonus should * be calculated * @param map * A Map indicating the BonusObj objects to be used in the * calculation and the source CDOMObjects for those BonusObj * objects * @return The bonus for the Player Character identified by the given * CharID, calculated from the BonusObj objects provided in the * given Map * */ public double calcBonus(CharID id, Map<BonusObj, ? extends CDOMObject> map) { double iBonus = 0; for (Map.Entry<BonusObj, ? extends CDOMObject> me : map.entrySet()) { BonusObj bonus = me.getKey(); CDOMObject source = me.getValue(); iBonus += getBonusValue(id, bonus, source.getQualifiedKey()) .doubleValue(); } return iBonus; } /** * Calculates the bonus provided by a specific BonusObj object when provided * by the source identified by the given String. * * @param id * The CharID identifying the Player Character for which the * bonus provided by the given BonusObj should be returned * @param bonus * The BonusObj for which the bonus calculation should take place * @param sourceIdentifier * The String identifier of the source of the BonusObj; required * in order to calculate object-specific variables which may be * in the formula of the BonusObj object * @return The bonus provided by a specific BonusObj object when provided by * the source identified by the given String */ private Number getBonusValue(CharID id, BonusObj bonus, String sourceIdentifier) { PlayerCharacter pc = trackingFacet.getPC(id); return bonus.resolve(pc, sourceIdentifier); } /** * Returns the sum of all bonus values provided by the Collection of * BonusObj objects when provided by the source identified by the given * String. * * This method is reference-semantic in that ownership of the Collection * which is passed to this method is not transferred to this method. This * method guarantees that no modifications are made to the provided * Collection, and no reference to the given Collection will be retained by * BonusCheckingFacet. * * @param id * The CharID identifying the Player Character for which the * bonus provided by the given Collection of BonusObj objects * should be returned * @param bonuses * The Collection of BonusObj objects for which the bonus * calculation should take place * @param sourceIdentifier * The String identifier of the source of the BonusObj; required * in order to calculate object-specific variables which may be * in the formula of the BonusObj object * @return The sum of all bonus values provided by the Collection of * BonusObj objects when provided by the source identified by the * given String */ public double getAllBonusValues(CharID id, Collection<BonusObj> bonuses, String sourceIdentifier) { PlayerCharacter pc = trackingFacet.getPC(id); double value = 0; for (BonusObj bo : bonuses) { value += bo.resolve(pc, sourceIdentifier).doubleValue(); } return value; } /** * Get back a Collection of bonus info with %LIST entries replaced with the * choices made. * * This method is value-semantic in that ownership of the returned * Collection is transferred to the class calling this method. Since this is * a remove all function, modification of the returned Collection will not * modify this BonusCheckingFacet and modification of this * BonusCheckingFacet will not modify the returned Collection. Modifications * to the returned Collection will also not modify any future or previous * objects returned by this (or other) methods on BonusCheckingFacet. If you * wish to modify the information stored in this BonusCheckingFacet, you * must use the add*() and remove*() methods of BonusCheckingFacet. * * @param id * The CharID identifying the Player Character for which the list * of bonus information should be returned * @param bonusName * The Bonus name used to select which Bonus objects to expand to * get their information * @return A Collection of bonus info with %LIST entries replaced with the * choices made */ public Collection<String> getExpandedBonusInfo(CharID id, String bonusName) { PlayerCharacter pc = trackingFacet.getPC(id); List<String> list = new ArrayList<>(); for (BonusObj bonus : pc.getActiveBonusList()) { if (bonus.getTypeOfBonus().equals(bonusName)) { String bonusInfo = bonus.getBonusInfo(); if (bonusInfo.contains("%LIST")) { // We have a %LIST that needs to be expanded List<BonusPair> bpList = pc.getStringListFromBonus(bonus); for (BonusPair bonusPair : bpList) { String key = bonusPair.fullyQualifiedBonusType; // Strip off the bonus name and the trailing . if (key.startsWith(bonusName)) { key = key.substring(bonusName.length()+1); } list.add(key); } } else { list.add(bonus.getBonusInfo()); } } } return list; } }