use of pcgen.cdom.inst.PCClassLevel in project pcgen by PCGen.
the class DomainApplication method removeDomainsForLevel.
public static void removeDomainsForLevel(PCClass cl, final int removedLevel, final PlayerCharacter aPC) {
/*
* Note this uses ALL of the domains up to and including this level,
* because there is the possibility (albeit strange) that the PC was
* qualified at a previous level change, but the PlayerCharacter is now
* not qualified for the given Domain. Even this has quirks, since it is
* only applied at the time of level increase, but I think that quirk
* should be resolved by a CDOM system around 6.0 - thpr 10/23/06
*/
for (QualifiedObject<CDOMSingleRef<Domain>> qo : cl.getSafeListFor(ListKey.DOMAIN)) {
CDOMSingleRef<Domain> ref = qo.getObject(aPC, cl);
if (ref == null) {
ref = qo.getRawObject();
aPC.removeDomain(ref.get());
}
}
for (int i = 0; i <= removedLevel; i++) {
// TODO This stinks for really high level characters - can this ever
// get null back?
PCClassLevel pcl = aPC.getActiveClassLevel(cl, i);
for (QualifiedObject<CDOMSingleRef<Domain>> qo : pcl.getSafeListFor(ListKey.DOMAIN)) {
CDOMSingleRef<Domain> ref = qo.getObject(aPC, cl);
if ((ref == null) || (i == removedLevel)) {
ref = qo.getRawObject();
aPC.removeDomain(ref.get());
}
}
}
}
use of pcgen.cdom.inst.PCClassLevel in project pcgen by PCGen.
the class SpellSupportForPCClass method updateSpellCache.
public boolean updateSpellCache(boolean force) {
if (force || !spellCacheValid) {
SpellProgressionCache cache = new SpellProgressionCache();
for (PCClassLevel cl : source.getOriginalClassLevelCollection()) {
Integer lvl = cl.get(IntegerKey.LEVEL);
List<Formula> cast = cl.getListFor(ListKey.CAST);
if (cast != null) {
cache.setCast(lvl, cast);
}
List<Formula> known = cl.getListFor(ListKey.KNOWN);
if (known != null) {
cache.setKnown(lvl, known);
}
List<Formula> spec = cl.getListFor(ListKey.SPECIALTYKNOWN);
if (spec != null) {
cache.setSpecialtyKnown(lvl, spec);
}
}
if (!cache.isEmpty()) {
spellCache = cache;
}
spellCacheValid = true;
}
return spellCache != null;
}
use of pcgen.cdom.inst.PCClassLevel in project pcgen by PCGen.
the class PCClassKeyChange method changeReferences.
public static void changeReferences(String oldClass, PCClass pcc) {
String newClass = pcc.getKeyName();
// Don't traverse the list if the names are the same
if (oldClass.equals(newClass)) {
return;
}
renameVariables(oldClass, pcc, newClass);
renameBonusTarget(pcc, oldClass, newClass);
// Repeat for Class Levels
for (PCClassLevel pcl : pcc.getOriginalClassLevelCollection()) {
renameVariables(oldClass, pcl, newClass);
renameBonusTarget(pcl, oldClass, newClass);
}
}
use of pcgen.cdom.inst.PCClassLevel in project pcgen by PCGen.
the class PCGVer2Parser method parseClassAbilitiesLevelLine.
private void parseClassAbilitiesLevelLine(final String line, final List<PCLevelInfo> pcLevelInfoList) {
final PCGTokenizer tokens;
try {
tokens = new PCGTokenizer(line);
} catch (PCGParseException pcgpex) {
final String message = LanguageBundle.getFormattedString(//$NON-NLS-1$
"Warnings.PCGenParser.IllegalClassAbility", line, pcgpex.getMessage());
warnings.add(message);
return;
}
int level = -1;
PCClass aPCClass = null;
PCGElement element;
PCLevelInfo pcl = null;
final Iterator<PCGElement> it = tokens.getElements().iterator();
// eg: Cleric=4
if (it.hasNext()) {
element = it.next();
final int index = element.getText().indexOf('=');
if (index < 0) {
final String message = LanguageBundle.getFormattedString(//$NON-NLS-1$
"Warnings.PCGenParser.InvalidClassLevel", element.getText());
warnings.add(message);
return;
}
final String classKeyName = EntityEncoder.decode(element.getText().substring(0, index));
aPCClass = thePC.getClassKeyed(classKeyName);
if (aPCClass == null) {
final String message = LanguageBundle.getFormattedString(//$NON-NLS-1$
"Warnings.PCGenParser.ClassNotFound", classKeyName);
warnings.add(message);
return;
}
try {
level = Integer.parseInt(element.getText().substring(index + 1));
} catch (NumberFormatException nfe) {
final String message = LanguageBundle.getFormattedString(//$NON-NLS-1$
"Warnings.PCGenParser.InvalidClassLevel", element.getText());
warnings.add(message);
return;
}
if (level < 1) {
final String message = LanguageBundle.getFormattedString(//$NON-NLS-1$
"Warnings.PCGenParser.InvalidClassLevel", element.getText());
warnings.add(message);
return;
}
for (PCLevelInfo info : pcLevelInfoList) {
if (classKeyName.equalsIgnoreCase(info.getClassKeyName()) && level == info.getClassLevel()) {
pcl = info;
break;
}
}
if (pcl == null) {
pcl = thePC.addLevelInfo(classKeyName);
pcl.setClassLevel(level);
} else {
thePC.addLevelInfo(pcl);
}
pcl.setSkillPointsRemaining(0);
}
while (it.hasNext()) {
element = it.next();
String tag = element.getName();
if (IOConstants.TAG_SUBSTITUTIONLEVEL.equals(tag)) {
final String substitutionClassKeyName = EntityEncoder.decode(element.getText());
SubstitutionClass aSubstitutionClass = aPCClass.getSubstitutionClassKeyed(substitutionClassKeyName);
if (aSubstitutionClass == null) {
final String message = LanguageBundle.getFormattedString(//$NON-NLS-1$
"Warnings.PCGenParser.ClassNotFound", substitutionClassKeyName);
warnings.add(message);
return;
}
SubstitutionLevelSupport.applyLevelArrayModsToLevel(aSubstitutionClass, aPCClass, level, thePC);
thePC.setSubstitutionClassName(thePC.getActiveClassLevel(aPCClass, level), substitutionClassKeyName);
} else if (IOConstants.TAG_HITPOINTS.equals(tag)) {
try {
PCClassLevel classLevel = thePC.getActiveClassLevel(aPCClass, level - 1);
thePC.setHP(classLevel, Integer.valueOf(element.getText()));
} catch (NumberFormatException nfe) {
final String message = LanguageBundle.getFormattedString(//$NON-NLS-1$
"Warnings.PCGenParser.InvalidHP", tag, element.getText());
warnings.add(message);
}
} else if (IOConstants.TAG_SAVES.equals(tag)) {
for (final PCGElement child : element.getChildren()) {
final String dString = EntityEncoder.decode(child.getText());
if (dString.startsWith(IOConstants.TAG_BONUS + IOConstants.TAG_SEPARATOR)) {
String bonusString = dString.substring(6);
int pipeLoc = bonusString.indexOf('|');
if (pipeLoc != -1) {
CDOMObject target = aPCClass;
String potentialInt = bonusString.substring(0, pipeLoc);
try {
int bonusLevel = Integer.parseInt(potentialInt);
if (bonusLevel > 0) {
target = thePC.getActiveClassLevel(aPCClass, bonusLevel);
}
bonusString = bonusString.substring(pipeLoc + 1);
} catch (NumberFormatException e) {
//OK (no level embedded in file)
if (level > 0) {
target = thePC.getActiveClassLevel(aPCClass, level);
}
}
BonusAddition.applyBonus(bonusString, "", thePC, target);
}
}
}
} else if (IOConstants.TAG_SPECIALTIES.equals(tag)) {
for (final PCGElement child : element.getChildren()) {
thePC.setAssoc(aPCClass, AssociationKey.SPECIALTY, EntityEncoder.decode(child.getText()));
}
} else if (IOConstants.TAG_SPECIALABILITIES.equals(tag)) {
for (PCGElement child : element.getChildren()) {
String specialAbilityName = EntityEncoder.decode(child.getText());
if (pcgenVersion[0] <= 5 && pcgenVersion[1] <= 5 && pcgenVersion[2] < 6) {
if (//$NON-NLS-1$
specialAbilityName.equals("Turn Undead")) {
//$NON-NLS-1$
parseFeatLine("FEAT:Turn Undead|TYPE:SPECIAL.TURNUNDEAD|DESC:");
continue;
} else if (//$NON-NLS-1$
specialAbilityName.equals("Rebuke Undead")) {
//$NON-NLS-1$
parseFeatLine("FEAT:Rebuke Undead|TYPE:SPECIAL.TURNUNDEAD|DESC:");
continue;
}
}
SpecialAbility specialAbility = new SpecialAbility(specialAbilityName);
CDOMObject target = aPCClass;
if (level > 0) {
target = thePC.getActiveClassLevel(aPCClass, level);
}
if (!thePC.hasSpecialAbility(specialAbilityName)) {
thePC.addUserSpecialAbility(specialAbility, target);
}
}
} else if (tag.equals(IOConstants.TAG_LEVELABILITY)) {
parseLevelAbilityInfo(element, aPCClass, level);
} else if (tag.equals(IOConstants.TAG_ADDTOKEN)) {
parseAddTokenInfo(element, thePC.getActiveClassLevel(aPCClass, level));
} else //
if (tag.equals(IOConstants.TAG_PRESTAT) || tag.equals(IOConstants.TAG_POSTSTAT)) {
boolean isPre = false;
if (tag.equals(IOConstants.TAG_PRESTAT)) {
isPre = true;
}
final int idx = element.getText().indexOf('=');
if (idx > 0) {
String statAbb = element.getText().substring(0, idx);
final PCStat pcstat = Globals.getContext().getReferenceContext().silentlyGetConstructedCDOMObject(PCStat.class, statAbb);
if (pcstat != null) {
try {
thePC.saveStatIncrease(pcstat, Integer.parseInt(element.getText().substring(idx + 1)), isPre);
} catch (NumberFormatException nfe) {
final String msg = LanguageBundle.getFormattedString(//$NON-NLS-1$
"Warnings.PCGenParser.InvalidStatMod", tag, element.getText());
warnings.add(msg);
}
} else {
final String msg = LanguageBundle.getFormattedString(//$NON-NLS-1$
"Warnings.PCGenParser.UnknownStat", tag, element.getText());
warnings.add(msg);
}
} else {
final String msg = LanguageBundle.getFormattedString(//$NON-NLS-1$
"Warnings.PCGenParser.MissingEquals", tag, element.getText());
warnings.add(msg);
}
} else if ((pcl != null) && IOConstants.TAG_SKILLPOINTSGAINED.equals(tag)) {
pcl.setFixedSkillPointsGained(Integer.parseInt(element.getText()));
} else if ((pcl != null) && IOConstants.TAG_SKILLPOINTSREMAINING.equals(tag)) {
pcl.setSkillPointsRemaining(Integer.parseInt(element.getText()));
} else if (IOConstants.TAG_DATA.equals(tag)) {
// TODO
// for now it's ok to ignore it!
} else {
final String msg = LanguageBundle.getFormattedString(//$NON-NLS-1$
"Warnings.PCGenParser.UnknownTag", tag, element.getText());
warnings.add(msg);
}
}
// TODO:
// process data
//
// need to add some consistency checks here to avoid
// - duplicate entries for one and the same class/level pair
// - missing entries for a given class/level pair
}
use of pcgen.cdom.inst.PCClassLevel in project pcgen by PCGen.
the class PCGIOHandler method sanityChecks.
/*
* ###############################################################
* private helper methods
* ###############################################################
*/
private void sanityChecks(PlayerCharacter currentPC, PCGParser parser) {
// Hit point sanity check
boolean fixMade = false;
resolveDuplicateEquipmentSets(currentPC);
// First make sure the "working" equipment list
// is in effect for all the bonuses it may add
currentPC.setCalcEquipmentList();
// make sure the bonuses from companions are applied
currentPC.setCalcFollowerBonus();
// pre-calculate all the bonuses
currentPC.calcActiveBonuses();
final int oldHp = currentPC.hitPoints();
// Recalc the feat pool if required
if (parser.isCalcFeatPoolAfterLoad()) {
double baseFeatPool = parser.getBaseFeatPool();
double featPoolBonus = currentPC.getRemainingFeatPoints(true);
baseFeatPool -= featPoolBonus;
currentPC.setUserPoolBonus(AbilityCategory.FEAT, new BigDecimal(baseFeatPool));
}
for (CNAbility aFeat : currentPC.getPoolAbilities(AbilityCategory.FEAT, Nature.NORMAL)) {
if (aFeat.getAbility().getSafe(ObjectKey.MULTIPLE_ALLOWED) && !currentPC.hasAssociations(aFeat)) {
warnings.add("Multiple selection feat found with no selections (" + aFeat.getAbility().getDisplayName() + "). Correct on Feat tab.");
}
}
//PCTemplate aTemplate = null;
if (currentPC.hasClass()) {
for (PCClass pcClass : currentPC.getClassSet()) {
// Ignore if no levels
if (currentPC.getLevel(pcClass) < 1) {
continue;
}
for (int i = 1; i <= currentPC.getLevel(pcClass); i++) {
int baseSides = currentPC.getLevelHitDie(pcClass, i).getDie();
//TODO i-1 is strange see CODE-1925
PCClassLevel pcl = currentPC.getActiveClassLevel(pcClass, i - 1);
Integer hp = currentPC.getHP(pcl);
int iRoll = hp == null ? 0 : hp;
int iSides = baseSides + (int) pcClass.getBonusTo("HD", "MAX", i, currentPC);
if (iRoll > iSides) {
currentPC.setHP(pcl, iSides);
fixMade = true;
}
}
}
}
if (fixMade) {
final String message = "Fixed illegal value in hit points. " + "Current character hit points: " + currentPC.hitPoints() + " not " + oldHp;
warnings.add(message);
}
//
for (PCClass pcClass : currentPC.getClassSet()) {
currentPC.calcActiveBonuses();
currentPC.calculateKnownSpellsForClassLevel(pcClass);
}
//
// need to calc the movement rates
currentPC.adjustMoveRates();
// re-calculate all the bonuses
currentPC.calcActiveBonuses();
// make sure we are not dirty
currentPC.setDirty(false);
}
Aggregations