Search in sources :

Example 26 with Type

use of pcgen.cdom.enumeration.Type in project pcgen by PCGen.

the class SkillCostDisplay method getModifierExplanation.

/**
	 * Builds up a string describing what makes up the misc modifier for a skill
	 * for a character. This can either be in long form '+2[skill TUMBLE gteq
	 * 5|TYPE=SYNERGY.STACK]' or in short form '+2[TUMBLE]'. Any modifiers that
	 * cannot be determined will be displayed as a single entry of 'OTHER'.
	 * 
	 * @param aPC
	 *            The character associated with this skill.
	 * @param shortForm
	 *            True if the abbreviated form should be used.
	 * @return The explanation of the misc modifier's make-up.
	 */
public static String getModifierExplanation(Skill sk, PlayerCharacter aPC, boolean shortForm) {
    double bonusObjTotal = 0.0;
    List<String> explanation = new ArrayList<>();
    String keyName = sk.getKeyName();
    String bonusKey = ("SKILL." + keyName).toUpperCase();
    for (BonusObj bonus : aPC.getActiveBonusList()) {
        // calculate bonus and add to activeBonusMap
        if (aPC.isApplied(bonus) && "SKILL".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));
                    bonusObjTotal += iBonus;
                }
            }
        }
    }
    StringBuilder bonusDetails = new StringBuilder();
    bonusDetails.append(StringUtil.joinToStringBuilder(explanation, " "));
    // TODO: Need to add other bonuses which are not encoded as bonus
    // objects
    // - familiars, racial, feats - and add them to bonusObjTotal
    double bonus;
    CDOMSingleRef<PCStat> statref = sk.get(ObjectKey.KEY_STAT);
    if (statref != null) {
        PCStat stat = statref.get();
        bonus = aPC.getStatModFor(stat);
        bonus += aPC.getTotalBonusTo("SKILL", "STAT." + stat.getKeyName());
        SkillCostDisplay.appendBonusDesc(bonusDetails, bonus, "STAT");
    }
    // The catch-all for non-bonusObj modifiers.
    bonus = aPC.getTotalBonusTo("SKILL", keyName) - bonusObjTotal;
    SkillCostDisplay.appendBonusDesc(bonusDetails, bonus, "OTHER");
    // loop through all current skill types checking for boni
    for (Type singleType : sk.getTrueTypeList(false)) {
        bonus = aPC.getTotalBonusTo("SKILL", "TYPE." + singleType);
        SkillCostDisplay.appendBonusDesc(bonusDetails, bonus, "TYPE." + singleType);
    }
    // now check for any lists of skills, etc
    bonus = aPC.getTotalBonusTo("SKILL", "LIST");
    SkillCostDisplay.appendBonusDesc(bonusDetails, bonus, "LIST");
    // now check for ALL
    bonus = aPC.getTotalBonusTo("SKILL", "ALL");
    SkillCostDisplay.appendBonusDesc(bonusDetails, bonus, "ALL");
    // function
    if (aPC.isClassSkill(sk)) {
        bonus = aPC.getTotalBonusTo("CSKILL", keyName);
        SkillCostDisplay.appendBonusDesc(bonusDetails, bonus, "CSKILL");
        // loop through all current skill types checking for boni
        for (Type singleType : sk.getTrueTypeList(false)) {
            bonus = aPC.getTotalBonusTo("CSKILL", "TYPE." + singleType);
            SkillCostDisplay.appendBonusDesc(bonusDetails, bonus, "CSKILL");
        }
        bonus = aPC.getTotalBonusTo("CSKILL", "LIST");
        SkillCostDisplay.appendBonusDesc(bonusDetails, bonus, "CSKILL");
    }
    if (!aPC.isClassSkill(sk) && !sk.getSafe(ObjectKey.EXCLUSIVE)) {
        bonus = aPC.getTotalBonusTo("CCSKILL", keyName);
        SkillCostDisplay.appendBonusDesc(bonusDetails, bonus, "CCSKILL");
        // loop through all current skill types checking for boni
        for (Type singleType : sk.getTrueTypeList(false)) {
            bonus = aPC.getTotalBonusTo("CCSKILL", "TYPE." + singleType);
            SkillCostDisplay.appendBonusDesc(bonusDetails, bonus, "CCSKILL");
        }
        bonus = aPC.getTotalBonusTo("CCSKILL", "LIST");
        SkillCostDisplay.appendBonusDesc(bonusDetails, bonus, "CCSKILL");
    }
    // Encumbrance
    int aCheckMod = sk.getSafe(ObjectKey.ARMOR_CHECK).calculateBonus(aPC);
    SkillCostDisplay.appendBonusDesc(bonusDetails, aCheckMod, "ARMOR");
    String aString = SettingsHandler.getGame().getRankModFormula();
    if (!aString.isEmpty()) {
        aString = aString.replaceAll(Pattern.quote("$$RANK$$"), SkillRankControl.getTotalRank(aPC, sk).toString());
        bonus = aPC.getVariableValue(aString, "").intValue();
        SkillCostDisplay.appendBonusDesc(bonusDetails, bonus, "RANKS");
    }
    return bonusDetails.toString();
}
Also used : Type(pcgen.cdom.enumeration.Type) BonusObj(pcgen.core.bonus.BonusObj) ArrayList(java.util.ArrayList) BonusPair(pcgen.core.bonus.BonusPair) PCStat(pcgen.core.PCStat)

Example 27 with Type

use of pcgen.cdom.enumeration.Type in project pcgen by PCGen.

the class PreSkillTester method passes.

/**
	 * @see pcgen.core.prereq.PrerequisiteTest#passes(pcgen.core.PlayerCharacter)
	 */
@Override
public int passes(final Prerequisite prereq, final PlayerCharacter character, CDOMObject source) {
    CharacterDisplay display = character.getDisplay();
    final int requiredRanks = Integer.parseInt(prereq.getOperand());
    // Compute the skill name from the Prerequisite
    String requiredSkillKey = prereq.getKey().toUpperCase();
    if (prereq.getSubKey() != null) {
        //$NON-NLS-1$ //$NON-NLS-2$
        requiredSkillKey += " (" + prereq.getSubKey().toUpperCase() + ')';
    }
    final boolean isType = //$NON-NLS-1$ //$NON-NLS-2$
    (requiredSkillKey.startsWith("TYPE.") || requiredSkillKey.startsWith("TYPE="));
    if (isType) {
        requiredSkillKey = requiredSkillKey.substring(5);
    }
    final String skillKey = requiredSkillKey;
    // Now locate all instances of this skillname and test them
    final int percentageSignPosition = skillKey.lastIndexOf('%');
    HashMap<Skill, Set<Skill>> serveAsSkills = new HashMap<>();
    Set<Skill> imitators = new HashSet<>();
    this.getImitators(serveAsSkills, imitators, display);
    int runningTotal = 0;
    boolean foundMatch = false;
    boolean foundSkill = false;
    for (Skill aSkill : display.getSkillSet()) {
        final String aSkillKey = aSkill.getKeyName().toUpperCase();
        if (isType) {
            if (percentageSignPosition >= 0) {
                foundMatch = matchesTypeWildCard(skillKey, percentageSignPosition, foundSkill, aSkill);
                foundSkill = (foundMatch) ? true : false;
                runningTotal = getRunningTotal(aSkill, character, prereq, foundMatch, runningTotal, requiredRanks);
            } else if (aSkill.isType(skillKey)) {
                foundMatch = true;
                foundSkill = true;
                runningTotal = getRunningTotal(aSkill, character, prereq, foundMatch, runningTotal, requiredRanks);
            }
            // If there wasn't a match, then check other skills of the type
            if (runningTotal == 0) {
                foundMatch = false;
            }
        } else if (aSkillKey.equals(skillKey) || ((percentageSignPosition >= 0) && aSkillKey.startsWith(skillKey.substring(0, percentageSignPosition)))) {
            foundMatch = true;
            foundSkill = true;
            runningTotal = getRunningTotal(aSkill, character, prereq, foundMatch, runningTotal, requiredRanks);
        }
        if (prereq.isCountMultiples() || prereq.isTotalValues()) {
            // For counted totals we want to count all occurances, not just the first
            foundMatch = false;
        }
        if (foundMatch) {
            break;
        }
    }
    if (!isType && !foundSkill) {
        for (Skill mock : serveAsSkills.keySet()) {
            Set<Skill> targets = serveAsSkills.get(mock);
            for (Skill target : targets) {
                if (foundSkill) {
                    break;
                }
                final String aSkillKey = target.getKeyName().toUpperCase();
                if (target.getDisplayName().equalsIgnoreCase(skillKey)) {
                    foundSkill = true;
                    foundMatch = true;
                    int theTotal = getRunningTotal(mock, character, prereq, foundMatch, runningTotal, requiredRanks);
                    runningTotal += theTotal;
                } else if (aSkillKey.equals(skillKey) || ((percentageSignPosition >= 0) && aSkillKey.startsWith(skillKey.substring(0, percentageSignPosition)))) {
                    foundSkill = true;
                    foundMatch = true;
                    int theTotal = getRunningTotal(mock, character, prereq, foundMatch, runningTotal, requiredRanks);
                    runningTotal += theTotal;
                }
            }
        }
    } else if (isType && !foundSkill) {
        for (Skill mock : serveAsSkills.keySet()) {
            Set<Skill> targets = serveAsSkills.get(mock);
            for (Skill target : targets) {
                if (foundSkill) {
                    break;
                }
                if (target.isType(skillKey)) {
                    foundSkill = true;
                    foundMatch = true;
                    int theTotal = getRunningTotal(mock, character, prereq, foundMatch, runningTotal, requiredRanks);
                    runningTotal += theTotal;
                } else if ((percentageSignPosition >= 0)) {
                    List<Type> mockTypes = target.getTrueTypeList(true);
                    for (Type mockType : mockTypes) {
                        foundMatch = matchesTypeWildCard(skillKey, percentageSignPosition, foundSkill, target);
                        foundSkill = (foundMatch) ? true : false;
                        runningTotal = getRunningTotal(mock, character, prereq, foundMatch, runningTotal, requiredRanks);
                        if (foundSkill) {
                            break;
                        }
                    }
                }
            }
        }
    }
    // doesn't have the skill we have to return a match
    if (foundSkill == false) {
        if (prereq.getOperator() == PrerequisiteOperator.LT) {
            runningTotal++;
        }
    }
    return countedTotal(prereq, runningTotal);
}
Also used : Skill(pcgen.core.Skill) Type(pcgen.cdom.enumeration.Type) Set(java.util.Set) HashSet(java.util.HashSet) HashMap(java.util.HashMap) CharacterDisplay(pcgen.core.display.CharacterDisplay) HashSet(java.util.HashSet)

Aggregations

Type (pcgen.cdom.enumeration.Type)27 ArrayList (java.util.ArrayList)6 MessageType (pcgen.core.utils.MessageType)6 EquipmentHead (pcgen.cdom.inst.EquipmentHead)4 Skill (pcgen.core.Skill)4 StringTokenizer (java.util.StringTokenizer)3 PCStat (pcgen.core.PCStat)3 BonusObj (pcgen.core.bonus.BonusObj)3 AttackType (pcgen.util.enumeration.AttackType)3 HashMap (java.util.HashMap)2 ClassSource (pcgen.cdom.helper.ClassSource)2 SpellSchool (pcgen.cdom.identifier.SpellSchool)2 ChangeArmorType (pcgen.cdom.processor.ChangeArmorType)2 ClassType (pcgen.core.ClassType)2 Equipment (pcgen.core.Equipment)2 WeaponProf (pcgen.core.WeaponProf)2 CharacterDisplay (pcgen.core.display.CharacterDisplay)2 ParseResult (pcgen.rules.persistence.token.ParseResult)2 HashSet (java.util.HashSet)1 LinkedHashSet (java.util.LinkedHashSet)1