use of pcgen.cdom.inst.PCClassLevel in project pcgen by PCGen.
the class AddTokenTest method testInvalidLevelNonClearLevel.
@Test
public void testInvalidLevelNonClearLevel() throws PersistenceLayerException {
primaryProf = new PCClassLevel();
primaryProf.put(IntegerKey.LEVEL, 1);
secondaryProf = new PCClassLevel();
secondaryProf.put(IntegerKey.LEVEL, 1);
assertFalse(parse(Constants.LST_DOT_CLEAR));
assertNoSideEffects();
}
use of pcgen.cdom.inst.PCClassLevel in project pcgen by PCGen.
the class ClassLevelChangeFacet method levelObjectChanged.
/**
* Triggered when the Level object of the Player Character changes (can
* occur due to substitution levels, for example)
*
* @param lce
* The ClassLevelObjectChangeEvent containing the information
* about the level change
* @see pcgen.cdom.facet.model.ClassFacet.ClassLevelChangeListener#levelObjectChanged(pcgen.cdom.facet.model.ClassFacet.ClassLevelObjectChangeEvent)
*/
@Override
public void levelObjectChanged(ClassLevelObjectChangeEvent lce) {
PCClassLevel old = lce.getOldLevel();
if (old != null) {
/*
* By defintion, if old is null, the replacement isn't meaningful
* for this facet
*/
CharID id = lce.getCharID();
PCClass pcc = lce.getPCClass();
if (classLevelFacet.remove(id, old, pcc)) {
/*
* Only add the new item if we had the old one "in" the PC
*/
classLevelFacet.add(id, lce.getNewLevel(), pcc);
}
}
}
use of pcgen.cdom.inst.PCClassLevel in project pcgen by PCGen.
the class ClassLoader method process.
@Override
public List<CDOMObject> process(StringBuilder sb, int line, String lineString, ConversionDecider decider) throws PersistenceLayerException, InterruptedException {
List<CDOMObject> list = new ArrayList<>();
String[] tokens = lineString.split(FIELD_SEPARATOR);
if (tokens.length == 0) {
return list;
}
String firstToken = tokens[0];
sb.append(firstToken);
Class<? extends CDOMObject> buildClass;
Class<? extends CDOMObject> buildParent = null;
if (firstToken.startsWith("SUBCLASS:")) {
buildClass = SubClass.class;
} else if (firstToken.startsWith("SUBCLASSLEVEL:")) {
buildClass = PCClassLevel.class;
buildParent = SubClass.class;
} else if (firstToken.startsWith("SUBSTITUTIONCLASS:")) {
buildClass = SubstitutionClass.class;
} else if (firstToken.startsWith("SUBSTITUTIONLEVEL:")) {
buildClass = PCClassLevel.class;
buildParent = SubstitutionClass.class;
} else if (firstToken.startsWith("CLASS:")) {
buildClass = PCClass.class;
} else {
buildClass = PCClassLevel.class;
buildParent = PCClass.class;
}
for (int tok = 1; tok < tokens.length; tok++) {
String token = tokens[tok];
sb.append(FIELD_SEPARATOR);
if (token.isEmpty()) {
continue;
}
CDOMObject obj = context.getReferenceContext().constructCDOMObject(buildClass, line + "Test" + tok);
CDOMObject parent = null;
if (obj instanceof PCClassLevel) {
obj.put(IntegerKey.LEVEL, 1);
parent = context.getReferenceContext().constructCDOMObject(buildParent, line + "Test" + tok);
try {
// Ensure processing against the PCClassLevel cannot cause side effects on the parent class
obj.put(ObjectKey.TOKEN_PARENT, parent.clone());
} catch (CloneNotSupportedException e) {
Logging.errorPrint("Unable to preare a copy of " + parent);
}
}
List<CDOMObject> injected = processToken(sb, firstToken, obj, parent, token, decider, line);
if (injected != null) {
list.addAll(injected);
}
context.purge(obj);
if (parent != null) {
context.purge(parent);
}
TokenConverter.clearConstants();
}
return list;
}
use of pcgen.cdom.inst.PCClassLevel in project pcgen by PCGen.
the class AbstractAddListTokenTest method testFromClassLevel.
@Test
public void testFromClassLevel() throws PersistenceLayerException {
PCClassLevel source = create(PCClassLevel.class, "Source");
T granted = createGrantedObject();
processToken(source);
assertEquals(0, getCount());
classLevelFacet.add(id, source, this);
assertTrue(containsExpected(granted));
assertEquals((classLevelFacet == getTargetFacet()) ? 2 : 1, getCount());
classLevelFacet.remove(id, source, this);
assertEquals(0, getCount());
assertTrue(cleanedSideEffects());
}
use of pcgen.cdom.inst.PCClassLevel in project pcgen by PCGen.
the class PlayerCharacter method incrementClassLevel.
/**
* Change the number of levels a character has in a particular class. Note:
* It is assumed that this method is not used as part of loading a
* previously saved character.
*
* @param numberOfLevels
* The number of levels to add or remove. If a positive number is
* passed in then that many levels will be added. If the number
* of levels passed in is negative then that many levels will be
* removed from the specified class.
* @param globalClass
* The global class from the data store. The class as stored in
* the character will be compared to this one using the
* getClassNamed() method
* @param bSilent
* If true do not display any warning messages about adding or
* removing too many levels
* @param bypassPrereqs
* Whether we should bypass the checks as to whether or not the
* PC qualifies to take this class. If true, the checks will be
* bypassed
*/
public void incrementClassLevel(final int numberOfLevels, final PCClass globalClass, final boolean bSilent, final boolean bypassPrereqs) {
// If not importing, load the spell list
if (!importing) {
getSpellList();
}
// Make sure the character qualifies for the class if adding it
if (numberOfLevels > 0) {
if (!bypassPrereqs && !globalClass.qualifies(this, globalClass)) {
return;
}
Race race = getRace();
if (globalClass.isMonster() && !SettingsHandler.isIgnoreMonsterHDCap() && !race.isAdvancementUnlimited() && ((totalHitDice() + numberOfLevels) > race.maxHitDiceAdvancement()) && !bSilent) {
ShowMessageDelegate.showMessageDialog("Cannot increase Monster Hit Dice for this character beyond " + race.maxHitDiceAdvancement() + ". This character's current number of Monster Hit Dice is " + totalHitDice(), Constants.APPLICATION_NAME, MessageType.INFORMATION);
return;
}
}
// Check if the character already has the class.
PCClass pcClassClone = getClassKeyed(globalClass.getKeyName());
// If the character did not already have the class...
if (pcClassClone == null) {
// add the class even if setting to level 0
if (numberOfLevels >= 0) {
// Get a clone of the class so we don't modify the globals!
//Still required :(
pcClassClone = globalClass.clone();
// Make sure the clone was successful
if (pcClassClone == null) {
Logging.errorPrint("PlayerCharacter::incrementClassLevel => " + "Clone of class " + globalClass.getKeyName() + " failed!");
return;
}
// If not importing, add extra feats
if (!importing && classFacet.isEmpty(id)) {
adjustAbilities(AbilityCategory.FEAT, new BigDecimal(pcClassClone.getSafe(IntegerKey.START_FEATS)));
}
// Add the class to the character classes as level 0
classFacet.addClass(id, pcClassClone);
} else {
// mod is < 0 and character does not have class. Return.
return;
}
}
// Add or remove levels as needed
if (numberOfLevels > 0) {
for (int i = 0; i < numberOfLevels; ++i) {
int currentLevel = getLevel(pcClassClone);
final PCLevelInfo playerCharacterLevelInfo = addLevelInfo(pcClassClone.getKeyName());
// if we fail to add the level, remove and return
if (!pcClassClone.addLevel(false, bSilent, this, bypassPrereqs)) {
PCClassLevel failedpcl = getActiveClassLevel(pcClassClone, currentLevel + 1);
removeLevelInfo(pcClassClone.getKeyName());
return;
}
}
} else if (numberOfLevels < 0) {
for (int i = 0; i < -numberOfLevels; ++i) {
int currentLevel = getLevel(pcClassClone);
pcClassClone.subLevel(this);
PCLevelInfo removedLI = removeLevelInfo(pcClassClone.getKeyName());
int pointsToRemove = removedLI.getSkillPointsGained(this) - removedLI.getSkillPointsRemaining();
SkillRankControl.removeSkillsForTopLevel(this, pcClassClone, currentLevel, pointsToRemove);
}
}
calcActiveBonuses();
}
Aggregations