use of pcgen.core.spell.Spell in project pcgen by PCGen.
the class StatTokenTest method setUp.
@Override
protected void setUp() throws Exception {
super.setUp();
LoadContext context = Globals.getContext();
boots = new Equipment();
boots.setName("Boots of Dex");
BonusObj aBonus = Bonus.newBonus(context, "STAT|DEX|2|TYPE=Enhancement");
if (aBonus != null) {
boots.addToListFor(ListKey.BONUS, aBonus);
}
spell = new Spell();
spell.setName("Weasel's Slipperiness");
aBonus = Bonus.newBonus(context, "STAT|DEX|4|TYPE=Enhancement");
if (aBonus != null) {
spell.addToListFor(ListKey.BONUS, aBonus);
}
template1 = new PCTemplate();
template1.setName("Munchkiny Goodness I");
aBonus = Bonus.newBonus(context, "STAT|STR,CON,DEX|1|TYPE=Luck");
if (aBonus != null) {
template1.addToListFor(ListKey.BONUS, aBonus);
}
template2 = new PCTemplate();
template2.setName("Munchkiny Goodness II");
aBonus = Bonus.newBonus(context, "STAT|STR,CON,DEX|1|TYPE=Enhancement");
if (aBonus != null) {
template2.addToListFor(ListKey.BONUS, aBonus);
}
template3 = new PCTemplate();
template3.setName("Lock the stat");
template3.addToListFor(ListKey.STAT_MINVALUE, new StatLock(context.getReferenceContext().getCDOMReference(PCStat.class, "WIS"), FormulaFactory.getFormulaFor("12")));
template4 = new PCTemplate();
template4.setName("Unwise");
aBonus = Bonus.newBonus(context, "STAT|WIS|-8|TYPE=Enhancement");
if (aBonus != null) {
template4.addToListFor(ListKey.BONUS, aBonus);
}
}
use of pcgen.core.spell.Spell in project pcgen by PCGen.
the class WeaponTokenTest method testWpnFinesse.
/**
* Test the processing of a finesseable weapon both with and without weapon finesse
* and temporary bonuses.
*/
public void testWpnFinesse() {
PlayerCharacter character = getCharacter();
assertEquals("Prof should be longsword", "KEY_LONGSWORD", fineSword.get(ObjectKey.WEAPON_PROF).get().getKeyName());
LoadContext context = Globals.getContext();
character.addEquipment(fineSword);
EquipSet es = new EquipSet("0.1.3", "Longsword (Fine)", fineSword.getName(), fineSword);
character.addEquipSet(es);
character.setCalcEquipmentList();
// Test weapon profs effects on large weapons
WeaponToken token = new WeaponToken();
assertEquals("Fine sword", "+18/+13/+8/+3", token.getToken("WEAPON.3.BASEHIT", character, null));
// Now apply weapon finess and check dex is used rather than str
Ability wpnFinesse = new Ability();
wpnFinesse.setName("Weapon Finesse");
wpnFinesse.setCDOMCategory(AbilityCategory.FEAT);
wpnFinesse.put(StringKey.KEY_NAME, "Weapon Finesse");
final BonusObj wfBonus = Bonus.newBonus(context, "COMBAT|TOHIT.Finesseable|((max(STR,DEX)-STR)+SHIELDACCHECK)|TYPE=NotRanged");
wpnFinesse.addToListFor(ListKey.BONUS, wfBonus);
addAbility(AbilityCategory.FEAT, wpnFinesse);
assertEquals("Fine sword", "+19/+14/+9/+4", token.getToken("WEAPON.3.BASEHIT", character, null));
// Add a temp penalty to dex and check that it is applied
character.setUseTempMods(true);
Spell spell2 = new Spell();
spell2.setName("Concrete Boots");
final BonusObj aBonus = Bonus.newBonus(context, "STAT|DEX|-4");
if (aBonus != null) {
spell2.addToListFor(ListKey.BONUS, aBonus);
}
BonusObj penalty = spell2.getRawBonusList(character).get(0);
character.addTempBonus(penalty, spell2, character);
character.calcActiveBonuses();
assertEquals("Fine sword", "+18/+13/+8/+3", token.getToken("WEAPON.3.BASEHIT", character, null));
}
use of pcgen.core.spell.Spell in project pcgen by PCGen.
the class KnownspellsTokenTest method testUnparseNegativeLevel.
@Test
public void testUnparseNegativeLevel() throws PersistenceLayerException {
try {
CDOMGroupRef<Spell> all = primaryContext.getReferenceContext().getCDOMAllReference(Spell.class);
primaryProf.addToListFor(ListKey.KNOWN_SPELLS, new KnownSpellIdentifier(all, -3));
assertBadUnparse();
} catch (IllegalArgumentException e) {
//Good here too :)
}
}
use of pcgen.core.spell.Spell in project pcgen by PCGen.
the class SpelllevelLst method subParse.
private <CL extends Loadable & CDOMList<Spell>> boolean subParse(LoadContext context, CDOMObject obj, Class<CL> tagType, String tokString, String spellString, List<Prerequisite> prereqs) {
int equalLoc = tokString.indexOf(Constants.EQUALS);
if (equalLoc == -1) {
Logging.errorPrint("Expected an = in SPELLLEVEL " + "definition: " + tokString);
return false;
}
String casterString = tokString.substring(0, equalLoc);
String spellLevel = tokString.substring(equalLoc + 1);
Integer splLevel;
try {
splLevel = Integer.decode(spellLevel);
} catch (NumberFormatException nfe) {
Logging.errorPrint("Expected a number for SPELLLEVEL, found: " + spellLevel);
return false;
}
if (isEmpty(casterString) || hasIllegalSeparator(',', casterString)) {
return false;
}
StringTokenizer clTok = new StringTokenizer(casterString, Constants.COMMA);
List<CDOMReference<? extends CDOMList<Spell>>> slList = new ArrayList<>();
while (clTok.hasMoreTokens()) {
String classString = clTok.nextToken();
CDOMReference<CL> ref;
if (classString.startsWith("SPELLCASTER.")) {
/*
* This is actually a TYPE
*/
ref = context.getReferenceContext().getCDOMTypeReference(tagType, classString.substring(12));
} else {
ref = context.getReferenceContext().getCDOMReference(tagType, classString);
}
slList.add(ref);
}
if (hasIllegalSeparator(',', spellString)) {
return false;
}
StringTokenizer spTok = new StringTokenizer(spellString, ",");
while (spTok.hasMoreTokens()) {
String spellName = spTok.nextToken();
CDOMReference<Spell> sp = context.getReferenceContext().getCDOMReference(Spell.class, spellName);
for (CDOMReference<? extends CDOMList<Spell>> sl : slList) {
AssociatedPrereqObject tpr = context.getListContext().addToList(getTokenName(), obj, sl, sp);
tpr.setAssociation(AssociationKey.SPELL_LEVEL, splLevel);
tpr.addAllPrerequisites(prereqs);
}
}
return true;
}
use of pcgen.core.spell.Spell in project pcgen by PCGen.
the class SpellsLst method parseNonEmptyToken.
/**
* {@literal
* SPELLS:<spellbook name>|[<optional parameters, pipe deliminated>] |<spell
* name>[,<formula for DC>] |<spell name2>[,<formula2 for DC>] |PRExxx
* |PRExxx
*
* CASTERLEVEL=<formula> Casterlevel of spells TIMES=<formula> Cast Times
* per day, -1=At Will
*}
* @param sourceLine
* Line from the LST file without the SPELLS:
* @return spells list
*/
@Override
protected ParseResult parseNonEmptyToken(LoadContext context, CDOMObject obj, String sourceLine) {
if (obj instanceof Ungranted) {
return new ParseResult.Fail("Cannot use " + getTokenName() + " on an Ungranted object type: " + obj.getClass().getSimpleName(), context);
}
if ((sourceLine == null) || sourceLine.isEmpty()) {
return new ParseResult.Fail("Argument in " + getTokenName() + " cannot be empty", context);
}
if (sourceLine.equals(Constants.LST_DOT_CLEAR_ALL)) {
context.getListContext().removeAllFromList(getTokenName(), obj, Spell.SPELLS);
return ParseResult.SUCCESS;
}
ParsingSeparator sep = new ParsingSeparator(sourceLine, '|');
sep.addGroupingPair('[', ']');
sep.addGroupingPair('(', ')');
String spellBook = sep.next();
if (spellBook.isEmpty()) {
return new ParseResult.Fail("SpellBook in " + getTokenName() + " cannot be empty", context);
}
// Formula casterLevel = null;
String casterLevel = null;
String times = null;
String timeunit = null;
if (!sep.hasNext()) {
return new ParseResult.Fail(getTokenName() + ": minimally requires a Spell Name", context);
}
String token = sep.next();
while (true) {
if (token.startsWith("TIMES=")) {
if (times != null) {
return new ParseResult.Fail("Found two TIMES entries in " + getTokenName() + ": invalid: " + sourceLine, context);
}
times = token.substring(6);
if (times.isEmpty()) {
return new ParseResult.Fail("Error in Times in " + getTokenName() + ": argument was empty", context);
}
if (!sep.hasNext()) {
return new ParseResult.Fail(getTokenName() + ": minimally requires " + "a Spell Name (after TIMES=)", context);
}
token = sep.next();
} else if (token.startsWith("TIMEUNIT=")) {
if (timeunit != null) {
return new ParseResult.Fail("Found two TIMEUNIT entries in " + getTokenName() + ": invalid: " + sourceLine, context);
}
timeunit = token.substring(9);
if (timeunit.isEmpty()) {
return new ParseResult.Fail("Error in TimeUnit in " + getTokenName() + ": argument was empty", context);
}
if (!sep.hasNext()) {
return new ParseResult.Fail(getTokenName() + ": minimally requires " + "a Spell Name (after TIMEUNIT=)", context);
}
token = sep.next();
} else if (token.startsWith("CASTERLEVEL=")) {
if (casterLevel != null) {
return new ParseResult.Fail("Found two CASTERLEVEL entries in " + getTokenName() + ": invalid: " + sourceLine, context);
}
casterLevel = token.substring(12);
if (casterLevel.isEmpty()) {
return new ParseResult.Fail("Error in Caster Level in " + getTokenName() + ": argument was empty", context);
}
if (!sep.hasNext()) {
return new ParseResult.Fail(getTokenName() + ": minimally requires a " + "Spell Name (after CASTERLEVEL=)", context);
}
token = sep.next();
} else {
break;
}
}
if (times == null) {
times = "1";
}
if (token.isEmpty()) {
return new ParseResult.Fail("Spell arguments may not be empty in " + getTokenName() + ": " + sourceLine, context);
}
if (token.charAt(0) == ',') {
return new ParseResult.Fail(getTokenName() + " Spell arguments may not start with , : " + token, context);
}
if (token.charAt(token.length() - 1) == ',') {
return new ParseResult.Fail(getTokenName() + " Spell arguments may not end with , : " + token, context);
}
if (token.indexOf(",,") != -1) {
return new ParseResult.Fail(getTokenName() + " Spell arguments uses double separator ,, : " + token, context);
}
/*
* CONSIDER This is currently order enforcing the reference fetching to
* match the integration tests that we perform, and their current
* behavior. Not sure if this is really tbe best solution?
*
* See CDOMObject.
*/
DoubleKeyMap<CDOMReference<Spell>, AssociationKey<?>, Object> dkm = new DoubleKeyMap<>(LinkedHashMap.class, HashMap.class);
while (true) {
if (token.isEmpty()) {
return new ParseResult.Fail("Spell arguments may not end with comma or pipe in " + getTokenName() + ": " + sourceLine, context);
}
int commaLoc = token.indexOf(',');
String name = commaLoc == -1 ? token : token.substring(0, commaLoc);
CDOMReference<Spell> spell = context.getReferenceContext().getCDOMReference(Spell.class, name);
dkm.put(spell, AssociationKey.CASTER_LEVEL, casterLevel);
Formula timesFormula = FormulaFactory.getFormulaFor(times);
if (!timesFormula.isValid()) {
return new ParseResult.Fail("Times in " + getTokenName() + " was not valid: " + timesFormula.toString(), context);
}
dkm.put(spell, AssociationKey.TIMES_PER_UNIT, timesFormula);
if (timeunit != null) {
dkm.put(spell, AssociationKey.TIME_UNIT, timeunit);
}
dkm.put(spell, AssociationKey.SPELLBOOK, spellBook);
if (commaLoc != -1) {
dkm.put(spell, AssociationKey.DC_FORMULA, token.substring(commaLoc + 1));
}
if (!sep.hasNext()) {
// No prereqs, so we're done
finish(context, obj, dkm, null);
return ParseResult.SUCCESS;
}
token = sep.next();
if (looksLikeAPrerequisite(token)) {
break;
}
}
List<Prerequisite> prereqs = new ArrayList<>();
while (true) {
Prerequisite prereq = getPrerequisite(token);
if (prereq == null) {
return new ParseResult.Fail(" (Did you put spells after the " + "PRExxx tags in SPELLS:?)", context);
}
prereqs.add(prereq);
if (!sep.hasNext()) {
break;
}
token = sep.next();
}
finish(context, obj, dkm, prereqs);
return ParseResult.SUCCESS;
}
Aggregations