use of pcgen.core.PCClass in project pcgen by PCGen.
the class HitdieToken method parseNonEmptyToken.
@Override
protected ParseResult parseNonEmptyToken(LoadContext context, Race race, String value) {
try {
String lock = value;
int pipeLoc = lock.indexOf(Constants.PIPE);
if (pipeLoc != lock.lastIndexOf(Constants.PIPE)) {
return new ParseResult.Fail(getTokenName() + " has more than one pipe, " + "is not of format: <int>[|<prereq>]", context);
}
// Do not initialize, null is significant
CDOMReference<PCClass> owner = null;
if (pipeLoc != -1) {
// Has a limitation
String lockPre = lock.substring(pipeLoc + 1);
if (lockPre.startsWith("CLASS.TYPE=")) {
String substring = lock.substring(pipeLoc + 12);
if (substring.isEmpty()) {
return new ParseResult.Fail("Cannot have Empty Type Limitation in " + getTokenName() + ": " + value, context);
}
ParseResult pr = checkForIllegalSeparator('.', substring);
if (!pr.passed()) {
return pr;
}
owner = context.getReferenceContext().getCDOMTypeReference(PCCLASS_CLASS, substring.split("\\."));
} else if (lockPre.startsWith(Constants.LST_CLASS_EQUAL)) {
String substring = lock.substring(pipeLoc + 7);
if (substring.isEmpty()) {
return new ParseResult.Fail("Cannot have Empty Class Limitation in " + getTokenName() + ": " + value, context);
}
owner = context.getReferenceContext().getCDOMReference(PCCLASS_CLASS, substring);
} else {
return new ParseResult.Fail("Invalid Limitation in HITDIE: " + lockPre, context);
}
lock = lock.substring(0, pipeLoc);
}
Processor<HitDie> hdm;
if (lock.startsWith("%/")) {
// HITDIE:%/num --- divides the classes hit die by num.
int denom = Integer.parseInt(lock.substring(2));
if (denom <= 0) {
return new ParseResult.Fail(getTokenName() + " was expecting a Positive Integer " + "for dividing Lock, was : " + lock.substring(2), context);
}
hdm = new HitDieFormula(new DividingFormula(denom));
} else if (lock.startsWith("%*")) {
// HITDIE:%*num --- multiplies the classes hit die by num.
int mult = Integer.parseInt(lock.substring(2));
if (mult <= 0) {
return new ParseResult.Fail(getTokenName() + " was expecting a Positive " + "Integer for multiplying Lock, was : " + lock.substring(2), context);
}
hdm = new HitDieFormula(new MultiplyingFormula(mult));
} else if (lock.startsWith("%+")) {
// possibly redundant with BONUS:HD MAX|num
// HITDIE:%+num --- adds num to the classes hit die.
int add = Integer.parseInt(lock.substring(2));
if (add <= 0) {
return new ParseResult.Fail(getTokenName() + " was expecting a Positive " + "Integer for adding Lock, was : " + lock.substring(2), context);
}
hdm = new HitDieFormula(new AddingFormula(add));
} else if (lock.startsWith("%-")) {
// HITDIE:%-num --- subtracts num from the classes hit die.
// possibly redundant with BONUS:HD MAX|num if that will
// take negative numbers.
int sub = Integer.parseInt(lock.substring(2));
if (sub <= 0) {
return new ParseResult.Fail(getTokenName() + " was expecting a Positive " + "Integer for subtracting Lock, was : " + lock.substring(2), context);
}
hdm = new HitDieFormula(new SubtractingFormula(sub));
} else if (lock.startsWith("%up")) {
// HITDIE:%upnum --- moves the hit die num steps up the die size
// list d4,d6,d8,d10,d12. Stops at d12.
int steps = Integer.parseInt(lock.substring(3));
if (steps <= 0) {
return new ParseResult.Fail("Invalid Step Count: " + steps + " in " + getTokenName() + " up (must be positive)", context);
}
if (steps >= 5) {
return new ParseResult.Fail("Invalid Step Count: " + steps + " in " + getTokenName() + " up (too large)", context);
}
hdm = new HitDieStep(steps, new HitDie(12));
} else if (lock.startsWith("%Hup")) {
// HITDIE:%upnum --- moves the hit die num steps up the die size
// list d4,d6,d8,d10,d12. Stops at d12.
int steps = Integer.parseInt(lock.substring(4));
if (steps <= 0) {
return new ParseResult.Fail("Invalid Step Count: " + steps + " in " + getTokenName(), context);
}
hdm = new HitDieStep(steps, null);
} else if (lock.startsWith("%down")) {
// HITDIE:%downnum --- moves the hit die num steps down the die
// size
// list d4,d6,d8,d10,d12. Stops at d4.
int steps = Integer.parseInt(lock.substring(5));
if (steps <= 0) {
return new ParseResult.Fail("Invalid Step Count: " + steps + " in " + getTokenName() + " down (must be positive)", context);
}
if (steps >= 5) {
return new ParseResult.Fail("Invalid Step Count: " + steps + " in " + getTokenName() + " down (too large)", context);
}
hdm = new HitDieStep(-steps, new HitDie(4));
} else if (lock.startsWith("%Hdown")) {
// HITDIE:%downnum --- moves the hit die num steps down the die
// size
// list. No limit.
int steps = Integer.parseInt(lock.substring(6));
if (steps <= 0) {
return new ParseResult.Fail("Invalid Step Count: " + steps + " in " + getTokenName(), context);
}
hdm = new HitDieStep(-steps, null);
} else {
int i = Integer.parseInt(lock);
if (i <= 0) {
return new ParseResult.Fail("Invalid HitDie: " + i + " in " + getTokenName(), context);
}
// HITDIE:num --- sets the hit die to num regardless of class.
hdm = new HitDieLock(new HitDie(i));
}
Processor<HitDie> mod = owner == null ? hdm : new ContextProcessor<>(hdm, owner);
context.getObjectContext().put(race, ObjectKey.HITDIE, mod);
return ParseResult.SUCCESS;
} catch (NumberFormatException nfe) {
return new ParseResult.Fail("Invalid Number (must be an Integer) in " + getTokenName() + ": " + nfe.getLocalizedMessage(), context);
}
}
use of pcgen.core.PCClass in project pcgen by PCGen.
the class PreClassTest method testSpellcasterTypeWrongCasePass.
/**
* Test to ensure that a spellcaster type check is case insensitive
* @throws Exception
*/
public void testSpellcasterTypeWrongCasePass() throws Exception {
LoadContext context = Globals.getContext();
final PCClass pcClass = context.getReferenceContext().constructCDOMObject(PCClass.class, "MyClass");
BuildUtilities.setFact(pcClass, "SpellType", "Arcane");
context.unconditionallyProcess(pcClass.getOriginalClassLevel(1), "CAST", "5,4");
context.unconditionallyProcess(pcClass, "SPELLSTAT", "CHA");
context.getReferenceContext().buildDerivedObjects();
context.getReferenceContext().resolveReferences(null);
context.loadCampaignFacets();
final PlayerCharacter character = getCharacter();
character.incrementClassLevel(1, pcClass);
setPCStat(character, cha, 12);
final Prerequisite prereq = new Prerequisite();
prereq.setKind("class");
prereq.setKey("Spellcaster.Arcane");
prereq.setOperand("1");
prereq.setOperator(PrerequisiteOperator.GTEQ);
final PreClassTester test = new PreClassTester();
final int passes = test.passes(prereq, character, null);
assertEquals(1, passes);
}
use of pcgen.core.PCClass in project pcgen by PCGen.
the class PreClassTest method testNamedClassServesAs.
/**
* Test to ensure that a character with a ServeAs class can be found
* @throws Exception
*/
public void testNamedClassServesAs() throws Exception {
final PCClass pcClass = new PCClass();
pcClass.setName("MyClass");
final PCClass warrior = new PCClass();
warrior.setName("Warrior");
final PCClass ranger = new PCClass();
ranger.setName("Ranger");
pcClass.addToListFor(ListKey.SERVES_AS_CLASS, CDOMDirectSingleRef.getRef(warrior));
pcClass.addToListFor(ListKey.SERVES_AS_CLASS, CDOMDirectSingleRef.getRef(ranger));
final PlayerCharacter character = getCharacter();
character.incrementClassLevel(3, pcClass);
final Prerequisite prereq = new Prerequisite();
prereq.setKind("class");
prereq.setKey("Warrior");
prereq.setOperand("1");
prereq.setOperator(PrerequisiteOperator.GTEQ);
final PreClassTester test = new PreClassTester();
final int passes = test.passes(prereq, character, null);
assertEquals(1, passes);
}
use of pcgen.core.PCClass in project pcgen by PCGen.
the class PreClassTest method testLevelsTwoClasses.
public void testLevelsTwoClasses() throws Exception {
final PCClass pcClass = new PCClass();
pcClass.setName("MyClass");
BuildUtilities.setFact(pcClass, "SpellType", "Arcane");
final PCClass pcClass2 = new PCClass();
pcClass2.setName("MyClass2");
BuildUtilities.setFact(pcClass2, "SpellType", "Divine");
final PlayerCharacter character = getCharacter();
character.incrementClassLevel(1, pcClass);
final PreParserFactory factory = PreParserFactory.getInstance();
Prerequisite prereq = factory.parse("PRECLASS:2,MyClass=1,MyClass2=2");
assertEquals(false, PrereqHandler.passes(prereq, character, null));
character.incrementClassLevel(1, pcClass2);
assertEquals(false, PrereqHandler.passes(prereq, character, null));
character.incrementClassLevel(1, pcClass2);
assertEquals(true, PrereqHandler.passes(prereq, character, null));
}
use of pcgen.core.PCClass in project pcgen by PCGen.
the class PreClassTest method testNoLevelsFail.
/**
* Test to ensure that a character without a named class cannot be found
* @throws Exception
*/
public void testNoLevelsFail() throws Exception {
final PCClass pcClass = new PCClass();
pcClass.setName("Monk");
final PlayerCharacter character = getCharacter();
character.incrementClassLevel(1, pcClass);
final Prerequisite prereq = new Prerequisite();
prereq.setKind("class");
prereq.setKey("Monk");
prereq.setOperand("1");
prereq.setOperator(PrerequisiteOperator.LT);
final PreClassTester test = new PreClassTester();
final int passes = test.passes(prereq, character, null);
assertEquals(0, passes);
}
Aggregations