@Override public Float resolve(PlayerCharacter pc) { if (source.length() == 0) { return 0.0f; } return (float) pc.getTotalBonusTo("PCLEVEL", source); }
/** * 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"); // these next two if-blocks try to get BONUS:[C]CSKILL|TYPE=xxx|y to // 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(); }
/* (non-Javadoc) * @see pcgen.core.facade.SpellSupportFacade#getClassInfo(pcgen.core.facade.ClassFacade) */ @Override public String getClassInfo(ClassFacade spellcaster) { if (!(spellcaster instanceof PCClass)) { return ""; } PCClass aClass = (PCClass) spellcaster; SpellSupportForPCClass spellSupport = pc.getSpellSupport(aClass); int highestSpellLevel = spellSupport.getHighestLevelSpell(pc); final HtmlInfoBuilder b = new HtmlInfoBuilder(); b.append("<table border=1><tr><td><font size=-2><b>"); // $NON-NLS-1$ b.append(OutputNameFormatting.piString(aClass, false)).append(" ["); // $NON-NLS-1$ b.append( String.valueOf( charDisplay.getLevel(aClass) + (int) pc.getTotalBonusTo("PCLEVEL", aClass.getKeyName()))); // $NON-NLS-1$ b.append("]</b></font></td>"); // $NON-NLS-1$ for (int i = 0; i <= highestSpellLevel; ++i) { b.append("<td><font size=-2><b><center> "); // $NON-NLS-1$ b.append(String.valueOf(i)); b.append(" </b></center></font></td>"); // $NON-NLS-1$ } b.append("</tr>"); // $NON-NLS-1$ b.append("<tr><td><font size=-1><b>Cast</b></font></td>"); // $NON-NLS-1$ for (int i = 0; i <= highestSpellLevel; ++i) { b.append("<td><font size=-1><center>"); // $NON-NLS-1$ b.append(getNumCast(aClass, i, pc)); b.append("</center></font></td>"); // $NON-NLS-1$ } b.append("</tr>"); // $NON-NLS-1$ // Making sure KnownList can be handled safely and produces the correct behaviour if (spellSupport.hasKnownList() || spellSupport.hasKnownSpells(pc)) { b.append("<tr><td><font size=-1><b>Known</b></font></td>"); // $NON-NLS-1$ for (int i = 0; i <= highestSpellLevel; ++i) { final int a = spellSupport.getKnownForLevel(i, pc); final int bonus = spellSupport.getSpecialtyKnownForLevel(i, pc); b.append("<td><font size=-1><center>"); // $NON-NLS-1$ b.append(String.valueOf(a)); if (bonus > 0) { b.append('+').append(Integer.toString(bonus)); } b.append("</center></font></td>"); // $NON-NLS-1$ } b.append("</tr>"); // $NON-NLS-1$ } b.append("<tr><td><font size=-1><b>DC</b></font></td>"); // $NON-NLS-1$ for (int i = 0; i <= highestSpellLevel; ++i) { b.append("<td><font size=-1><center>"); // $NON-NLS-1$ b.append(String.valueOf(getDC(aClass, i, pc))); b.append("</center></font></td>"); // $NON-NLS-1$ } b.append("</tr></table>"); // $NON-NLS-1$ b.appendI18nElement("InfoSpells.caster.type", aClass.getSpellType()); // $NON-NLS-1$ b.appendLineBreak(); b.appendI18nElement("InfoSpells.stat.bonus", aClass.getSpellBaseStat()); // $NON-NLS-1$ if (pc.hasAssocs(aClass, AssociationKey.SPECIALTY) || charDisplay.hasDomains()) { boolean needComma = false; StringBuilder schoolInfo = new StringBuilder(); String spec = pc.getAssoc(aClass, AssociationKey.SPECIALTY); if (spec != null) { schoolInfo.append(spec); needComma = true; } for (Domain d : charDisplay.getSortedDomainSet()) { if (needComma) { schoolInfo.append(','); } needComma = true; schoolInfo.append(d.getKeyName()); } b.appendLineBreak(); b.appendI18nElement("InfoSpells.school", schoolInfo.toString()); // $NON-NLS-1$ } Set<String> set = new TreeSet<>(); for (SpellProhibitor sp : aClass.getSafeListFor(ListKey.PROHIBITED_SPELLS)) { set.addAll(sp.getValueList()); } Collection<? extends SpellProhibitor> prohibList = charDisplay.getProhibitedSchools(aClass); if (prohibList != null) { for (SpellProhibitor sp : prohibList) { set.addAll(sp.getValueList()); } } if (!set.isEmpty()) { b.appendLineBreak(); b.appendI18nElement( "InfoSpells.prohibited.school", //$NON-NLS-1$ StringUtil.join(set, ",")); // $NON-NLS-1$ } String bString = SourceFormat.getFormattedString(aClass, Globals.getSourceDisplay(), true); if (bString.length() > 0) { b.appendLineBreak(); b.appendI18nElement("in_source", bString); // $NON-NLS-1$ } return b.toString(); }