use of pcgen.core.bonus.BonusPair in project pcgen by PCGen.
the class BonusCheckingFacet method getExpandedBonusInfo.
/**
* 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;
}
use of pcgen.core.bonus.BonusPair in project pcgen by PCGen.
the class SkillCostDisplay method getSituationModifierExplanation.
public static String getSituationModifierExplanation(Skill sk, String situation, PlayerCharacter aPC, boolean shortForm) {
List<String> explanation = new ArrayList<>();
String keyName = sk.getKeyName();
String bonusKey = ("SITUATION." + keyName + "=" + situation).toUpperCase();
for (BonusObj bonus : aPC.getActiveBonusList()) {
// calculate bonus and add to activeBonusMap
if (aPC.isApplied(bonus) && "SITUATION".equals(bonus.getBonusName())) {
boolean include = bonusForThisSkill(bonus, keyName);
if (!include) {
for (BonusPair bp : aPC.getStringListFromBonus(bonus)) {
String bpKey = bp.fullyQualifiedBonusType.toUpperCase();
if (bpKey.equals(bonusKey)) {
include = true;
break;
}
}
}
if (include) {
double iBonus = 0;
for (BonusPair bp : aPC.getStringListFromBonus(bonus)) {
String bpKey = bp.fullyQualifiedBonusType.toUpperCase();
if (bpKey.startsWith(bonusKey)) {
iBonus += bp.resolve(aPC).doubleValue();
}
}
if (!CoreUtility.doublesEqual(iBonus, 0.0)) {
explanation.add(Delta.toString((int) iBonus) + aPC.getBonusContext(bonus, shortForm));
}
}
}
}
return StringUtil.join(explanation, " ");
}
use of pcgen.core.bonus.BonusPair in project pcgen by PCGen.
the class BonusManager method getPartialStatBonusFor.
public int getPartialStatBonusFor(PCStat stat, boolean useTemp, boolean useEquip) {
String statAbbr = stat.getKeyName();
final String prefix = "STAT." + statAbbr;
Map<String, String> bonusMap = new HashMap<>();
Map<String, String> nonStackMap = new ConcurrentHashMap<>();
Map<String, String> stackMap = new ConcurrentHashMap<>();
for (BonusObj bonus : getActiveBonusList()) {
if (pc.isApplied(bonus) && bonus.getBonusName().equals("STAT")) {
boolean found = false;
Object co = getSourceObject(bonus);
for (Object element : bonus.getBonusInfoList()) {
if (element instanceof PCStat && element.equals(stat)) {
found = true;
break;
}
// parisng.
if (element instanceof MissingObject) {
String name = ((MissingObject) element).getObjectName();
if (("%LIST".equals(name) || "LIST".equals(name)) && co instanceof CDOMObject) {
CDOMObject creator = (CDOMObject) co;
for (String assoc : pc.getConsolidatedAssociationList(creator)) {
//TODO Case sensitivity?
if (assoc.contains(statAbbr)) {
found = true;
break;
}
}
}
}
}
if (!found) {
continue;
}
// The bonus has been applied to the target stat
// Should it be included?
boolean addIt = false;
if (co instanceof Equipment || co instanceof EquipmentModifier) {
addIt = useEquip;
} else if (co instanceof Ability) {
List<String> types = ((Ability) co).getTypes();
if (types.contains("Equipment")) {
addIt = useEquip;
} else {
addIt = true;
}
} else if (tempBonusBySource.containsKey(bonus)) {
addIt = useTemp;
} else {
addIt = true;
}
if (addIt) {
// bonuses with the stacking rules applied.
for (BonusPair bp : getStringListFromBonus(bonus)) {
if (bp.fullyQualifiedBonusType.startsWith(prefix)) {
setActiveBonusStack(bp.resolve(pc).doubleValue(), bp.fullyQualifiedBonusType, nonStackMap, stackMap);
totalBonusesForType(nonStackMap, stackMap, bp.fullyQualifiedBonusType, bonusMap);
}
}
}
}
}
// Sum the included bonuses to the stat to get our result.
int total = 0;
for (String bKey : bonusMap.keySet()) {
total += Float.parseFloat(bonusMap.get(bKey));
}
return total;
}
use of pcgen.core.bonus.BonusPair in project pcgen by PCGen.
the class BonusManager method buildActiveBonusMap.
/**
* Build the bonus HashMap from all active BonusObj's
*/
void buildActiveBonusMap() {
activeBonusMap = new ConcurrentHashMap<>();
cachedActiveBonusSumsMap = new ConcurrentHashMap<>();
Map<String, String> nonStackMap = new ConcurrentHashMap<>();
Map<String, String> stackMap = new ConcurrentHashMap<>();
Set<BonusObj> processedBonuses = new WrappedMapSet<>(IdentityHashMap.class);
//Logging.log(Logging.INFO, "=== Start bonus processing.");
//
// We do a first pass of just the "static" bonuses
// as they require less computation and no recursion
List<BonusObj> bonusListCopy = new ArrayList<>();
bonusListCopy.addAll(getActiveBonusList());
for (BonusObj bonus : bonusListCopy) {
if (!bonus.isValueStatic()) {
continue;
}
final Object source = getSourceObject(bonus);
if (source == null) {
if (Logging.isDebugMode()) {
Logging.debugPrint("BONUS: " + bonus + " ignored due to no creator");
}
continue;
}
// Keep track of which bonuses have been calculated
//Logging.log(Logging.INFO, "Processing bonus " + bonus + " - static.");
processedBonuses.add(bonus);
for (BonusPair bp : getStringListFromBonus(bonus)) {
final double iBonus = bp.resolve(pc).doubleValue();
setActiveBonusStack(iBonus, bp.fullyQualifiedBonusType, nonStackMap, stackMap);
totalBonusesForType(nonStackMap, stackMap, bp.fullyQualifiedBonusType, activeBonusMap);
if (Logging.isDebugMode()) {
String id;
if (source instanceof CDOMObject) {
id = ((CDOMObject) source).getDisplayName();
} else {
id = source.toString();
}
Logging.debugPrint("BONUS: " + id + " : " + iBonus + " : " + bp.fullyQualifiedBonusType);
}
}
}
//
// Now we do all the BonusObj's that require calculations
bonusListCopy = new ArrayList<>();
bonusListCopy.addAll(getActiveBonusList());
for (BonusObj bonus : getActiveBonusList()) {
if (processedBonuses.contains(bonus)) {
continue;
}
final CDOMObject anObj = (CDOMObject) getSourceObject(bonus);
if (anObj == null) {
continue;
}
try {
processBonus(bonus, new WrappedMapSet<>(IdentityHashMap.class), processedBonuses, nonStackMap, stackMap);
} catch (Exception e) {
Logging.errorPrint(e.getLocalizedMessage(), e);
continue;
}
}
}
use of pcgen.core.bonus.BonusPair in project pcgen by PCGen.
the class BonusManager method getStringListFromBonus.
public List<BonusPair> getStringListFromBonus(BonusObj bo) {
Object creatorObj = getSourceObject(bo);
List<String> associatedList;
CDOMObject anObj = null;
if (creatorObj instanceof CDOMObject) {
anObj = (CDOMObject) creatorObj;
associatedList = pc.getConsolidatedAssociationList(anObj);
if (associatedList == null || associatedList.isEmpty()) {
associatedList = NO_ASSOC_LIST;
}
} else {
associatedList = NO_ASSOC_LIST;
}
List<BonusPair> bonusList = new ArrayList<>();
// Must use getBonusName because it contains the unaltered bonusType
String bonusName = bo.getBonusName();
String[] bonusInfoArray = bo.getBonusInfo().split(",");
String bonusType = bo.getTypeString();
for (String assoc : associatedList) {
String replacedName;
if (bonusName.contains(VALUE_TOKEN_REPLACEMENT)) {
replacedName = bonusName.replaceAll(VALUE_TOKEN_PATTERN, assoc);
} else {
replacedName = bonusName;
}
List<String> replacedInfoList = new ArrayList<>(4);
for (String bonusInfo : bonusInfoArray) {
if (bonusInfo.contains(VALUE_TOKEN_REPLACEMENT)) {
replacedInfoList.add(bonusInfo.replaceAll(VALUE_TOKEN_PATTERN, assoc));
} else if (bonusInfo.contains(VAR_TOKEN_REPLACEMENT)) {
replacedInfoList.add(bonusName.replaceAll(VAR_TOKEN_PATTERN, assoc));
} else if (bonusInfo.equals(LIST_TOKEN_REPLACEMENT)) {
replacedInfoList.add(assoc);
} else {
replacedInfoList.add(bonusInfo);
}
}
Formula newFormula;
if (bo.isValueStatic()) {
newFormula = bo.getFormula();
} else {
String value = bo.getValue();
// A %LIST substitution also needs to be done in the val
// section
int listIndex = value.indexOf(VALUE_TOKEN_REPLACEMENT);
String thisValue = value;
if (listIndex >= 0) {
thisValue = value.replaceAll(VALUE_TOKEN_PATTERN, assoc);
}
//Need to protect against a selection not being made with a %LIST
if (thisValue.isEmpty()) {
thisValue = "0";
}
newFormula = FormulaFactory.getFormulaFor(thisValue);
}
for (String replacedInfo : replacedInfoList) {
StringBuilder sb = new StringBuilder(100);
sb.append(replacedName).append('.').append(replacedInfo);
if (bo.hasTypeString()) {
sb.append(':').append(bonusType);
}
bonusList.add(new BonusPair(sb.toString(), newFormula, creatorObj));
}
}
return bonusList;
}
Aggregations