use of pcgen.core.prereq.Prerequisite 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;
}
use of pcgen.core.prereq.Prerequisite in project pcgen by PCGen.
the class SpellknownLst method parseTokenWithSeparator.
@Override
protected ParseResult parseTokenWithSeparator(LoadContext context, CDOMObject obj, String value) {
if (obj instanceof Ungranted) {
return new ParseResult.Fail("Cannot use " + getTokenName() + " on an Ungranted object type: " + obj.getClass().getSimpleName(), context);
}
String workingValue = value;
List<Prerequisite> prereqs = new ArrayList<>();
while (true) {
int lastPipeLoc = workingValue.lastIndexOf('|');
if (lastPipeLoc == -1) {
return new ParseResult.Fail("Invalid " + getTokenName() + " not enough tokens: " + value, context);
}
String lastToken = workingValue.substring(lastPipeLoc + 1);
if (looksLikeAPrerequisite(lastToken)) {
workingValue = workingValue.substring(0, lastPipeLoc);
Prerequisite prerequisite = getPrerequisite(lastToken);
if (prerequisite == null) {
return new ParseResult.Fail("Invalid prerequisite " + lastToken + " in " + getTokenName() + " tag: " + value, context);
}
prereqs.add(prerequisite);
} else {
break;
}
}
StringTokenizer tok = new StringTokenizer(workingValue, Constants.PIPE);
if (tok.countTokens() < 3) {
return new ParseResult.Fail("Insufficient values in SPELLKNOWN tag: " + value, context);
}
// CLASS only
String tagType = tok.nextToken();
while (tok.hasMoreTokens()) {
String tokString = tok.nextToken();
String spellString = tok.nextToken();
if (tagType.equalsIgnoreCase("CLASS")) {
if (!subParse(context, obj, ClassSpellList.class, tokString, spellString, prereqs)) {
return ParseResult.INTERNAL_ERROR;
//return new ParseResult.Fail(" " + getTokenName()
// + " error - entire token was " + value, context);
}
} else {
return new ParseResult.Fail("First token of " + getTokenName() + " must be CLASS: " + value, context);
}
}
return ParseResult.SUCCESS;
}
use of pcgen.core.prereq.Prerequisite in project pcgen by PCGen.
the class VisionLst method parseTokenWithSeparator.
@Override
protected ParseResult parseTokenWithSeparator(LoadContext context, CDOMObject obj, String value) {
if (obj instanceof Ungranted) {
return new ParseResult.Fail("Cannot use " + getTokenName() + " on an Ungranted object type: " + obj.getClass().getSimpleName(), context);
}
StringTokenizer aTok = new StringTokenizer(value, Constants.PIPE);
String visionString = aTok.nextToken();
if (looksLikeAPrerequisite(visionString)) {
return new ParseResult.Fail("Cannot have only PRExxx subtoken in " + getTokenName() + ": " + value, context);
}
ArrayList<AssociatedPrereqObject> edgeList = new ArrayList<>();
boolean foundClear = false;
while (true) {
if (Constants.LST_DOT_CLEAR.equals(visionString)) {
context.getListContext().removeAllFromList(getTokenName(), obj, Vision.VISIONLIST);
foundClear = true;
} else if (visionString.startsWith(Constants.LST_DOT_CLEAR_DOT)) {
try {
Vision vis = Vision.getVision(visionString.substring(7));
context.getListContext().removeFromList(getTokenName(), obj, Vision.VISIONLIST, new CDOMDirectSingleRef<>(vis));
} catch (IllegalArgumentException e) {
ComplexParseResult cpr = new ComplexParseResult();
cpr.addErrorMessage("Bad Syntax for Cleared Vision in " + getTokenName());
cpr.addErrorMessage(e.getMessage());
return cpr;
}
foundClear = true;
} else if (looksLikeAPrerequisite(visionString)) {
break;
} else {
try {
Vision vision = Vision.getVision(visionString);
AssociatedPrereqObject edge = context.getListContext().addToList(getTokenName(), obj, Vision.VISIONLIST, new CDOMDirectSingleRef<>(vision));
edgeList.add(edge);
} catch (IllegalArgumentException e) {
ComplexParseResult cpr = new ComplexParseResult();
cpr.addErrorMessage("Bad Syntax for Vision in " + getTokenName());
cpr.addErrorMessage(e.getMessage());
return cpr;
}
}
if (!aTok.hasMoreTokens()) {
return ParseResult.SUCCESS;
}
visionString = aTok.nextToken();
}
if (foundClear) {
return new ParseResult.Fail("Cannot use PREREQs when using .CLEAR or .CLEAR. in " + getTokenName(), context);
}
while (true) {
Prerequisite prereq = getPrerequisite(visionString);
if (prereq == null) {
return new ParseResult.Fail(" (Did you put vision after the " + "PRExxx tags in " + getTokenName() + ":?)", context);
}
for (AssociatedPrereqObject edge : edgeList) {
edge.addPrerequisite(prereq);
}
if (!aTok.hasMoreTokens()) {
break;
}
visionString = aTok.nextToken();
}
return ParseResult.SUCCESS;
}
use of pcgen.core.prereq.Prerequisite in project pcgen by PCGen.
the class AspectToken method parseAspect.
/**
* Parses the ASPECT tag into a Aspect object.
*
* @param aspectDef
* The LST tag
* @return A <tt>Aspect</tt> object
*/
public Aspect parseAspect(final String name, final String aspectDef) {
final StringTokenizer tok = new StringTokenizer(aspectDef, Constants.PIPE);
String firstToken = tok.nextToken();
/*if (PreParserFactory.isPreReqString(firstToken))
{
Logging.errorPrint("Invalid " + getTokenName() + ": " + name);
Logging.errorPrint(" PRExxx can not be only value");
return null;
}*/
final Aspect aspect = new Aspect(name, EntityEncoder.decode(firstToken));
boolean isPre = false;
while (tok.hasMoreTokens()) {
final String token = tok.nextToken();
if (PreParserFactory.isPreReqString(token)) {
Prerequisite prereq = getPrerequisite(token);
if (prereq == null) {
Logging.errorPrint(getTokenName() + " had invalid prerequisite : " + token);
return null;
}
aspect.addPrerequisite(prereq);
isPre = true;
} else {
if (isPre) {
Logging.errorPrint("Invalid " + getTokenName() + ": " + name);
Logging.errorPrint(" PRExxx must be at the END of the Token");
return null;
}
aspect.addVariable(token);
}
}
return aspect;
}
use of pcgen.core.prereq.Prerequisite in project pcgen by PCGen.
the class BenefitToken method parseBenefit.
/**
* Parses the BENEFIT tag into a Description object.
*
* @param aDesc
* The LST tag
* @return A <tt>Description</tt> object
*/
public Description parseBenefit(final String aDesc) {
if (isEmpty(aDesc) || hasIllegalSeparator('|', aDesc)) {
return null;
}
final StringTokenizer tok = new StringTokenizer(aDesc, Constants.PIPE);
String firstToken = tok.nextToken();
if (PreParserFactory.isPreReqString(firstToken)) {
Logging.errorPrint("Invalid " + getTokenName() + ": " + aDesc);
Logging.errorPrint(" PRExxx can not be only value");
return null;
}
String ds = EntityEncoder.decode(firstToken);
if (!StringUtil.hasBalancedParens(ds)) {
Logging.log(Logging.LST_ERROR, getTokenName() + " encountered imbalanced Parenthesis: " + aDesc);
return null;
}
Description desc = new Description(ds);
boolean isPre = false;
while (tok.hasMoreTokens()) {
final String token = tok.nextToken();
if (PreParserFactory.isPreReqString(token)) {
Prerequisite prereq = getPrerequisite(token);
if (prereq == null) {
Logging.errorPrint(getTokenName() + " had invalid prerequisite : " + token);
return null;
}
desc.addPrerequisite(prereq);
isPre = true;
} else {
if (isPre) {
Logging.errorPrint("Invalid " + getTokenName() + ": " + aDesc);
Logging.errorPrint(" PRExxx must be at the END of the Token");
return null;
}
desc.addVariable(token);
}
}
return desc;
}
Aggregations