use of pcgen.base.formula.Formula in project pcgen by PCGen.
the class StartskillptsToken method parseNonEmptyToken.
@Override
protected ParseResult parseNonEmptyToken(LoadContext context, PCClass pcc, String value) {
Formula formula = FormulaFactory.getFormulaFor(value);
if (!formula.isValid()) {
return new ParseResult.Fail("Formula in " + getTokenName() + " was not valid: " + formula.toString(), context);
}
context.getObjectContext().put(pcc, FormulaKey.START_SKILL_POINTS, formula);
return ParseResult.SUCCESS;
}
use of pcgen.base.formula.Formula in project pcgen by PCGen.
the class EncounterPlugin method generateXofYEL.
/**
* Generates creatures for an encounter based on a specified Encounter
* Level and number of creatures.
* @param size the number of creatures needed for encounter.
* @param totalEL total experience level.
*/
private void generateXofYEL(String size, String totalEL) {
File f = new File(getDataDirectory() + File.separator + DIR_ENCOUNTER + File.separator + "4_1.xml");
ReadXML xml;
VectorTable table41;
Random roll = new Random(System.currentTimeMillis());
List<Race> critters = new ArrayList<>();
if (!f.exists()) {
//$NON-NLS-1$
Logging.errorPrintLocalised("in_plugin_encounter_error_missing", f);
return;
}
xml = new ReadXML(f);
if ((table41 = xml.getTable()) == null) {
Logging.errorPrint("ACK! error getting table41! " + f.toString());
return;
}
xml = null;
f = null;
// verrify values on the table.
String crs = (String) table41.crossReference(totalEL, size);
table41 = null;
if (crs == null) {
Logging.errorPrint("Tables do not match the given parameters (" + totalEL + ", " + size + ')');
return;
}
Formula crFormula = FormulaFactory.getFormulaFor(crs);
if (!crFormula.isValid()) {
Logging.errorPrint("CR Formula " + crs + " was not valid: " + crFormula.toString());
}
ChallengeRating cr = new ChallengeRating(crFormula);
// populate critters with a list of matching monsters with the right CR.
for (final Race race : Globals.getContext().getReferenceContext().getConstructedCDOMObjects(Race.class)) {
if (cr.equals(race.get(ObjectKey.CHALLENGE_RATING))) {
critters.add(race);
}
}
int i = roll.nextInt(critters.size());
for (int x = 0; x < Integer.parseInt(size); x++) {
theModel.addElement(critters.get(i).toString());
}
}
use of pcgen.base.formula.Formula 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.base.formula.Formula in project pcgen by PCGen.
the class RegionLst 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);
}
if (obj instanceof NonInteractive) {
return new ParseResult.Fail("Cannot use " + getTokenName() + " on an Non-Interactive object type: " + obj.getClass().getSimpleName(), context);
}
StringTokenizer tok = new StringTokenizer(value, Constants.PIPE);
String item = tok.nextToken();
Formula count = FormulaFactory.getFormulaFor(item);
if (!count.isValid()) {
return new ParseResult.Fail("Count in " + getTokenName() + " was not valid: " + count.toString(), context);
}
if (count.isStatic()) {
if (!tok.hasMoreTokens()) {
return new ParseResult.Fail(getTokenName() + " cannot have only a count: " + value, context);
}
item = tok.nextToken();
if (count.resolveStatic().intValue() <= 0) {
return new ParseResult.Fail("Count in " + getTokenName() + " must be > 0: " + value, context);
}
} else {
count = FormulaFactory.ONE;
}
List<Region> regions = new ArrayList<>();
while (true) {
regions.add(Region.getConstant(item));
if (!tok.hasMoreTokens()) {
break;
}
item = tok.nextToken();
}
SimpleChoiceSet<Region> rcs = new SimpleChoiceSet<>(regions);
ChoiceSet<Region> cs = new ChoiceSet<>(getTokenName(), rcs);
cs.setTitle("Region Selection");
TransitionChoice<Region> tc = new ConcreteTransitionChoice<>(cs, count);
context.getObjectContext().put(obj, ObjectKey.REGION_CHOICE, tc);
tc.setRequired(false);
tc.setChoiceActor(this);
return ParseResult.SUCCESS;
}
use of pcgen.base.formula.Formula in project pcgen by PCGen.
the class ClassSkillsLevelToken method parseNonEmptyToken.
@Override
protected ParseResult parseNonEmptyToken(LoadContext context, PCClassLevel obj, String value) {
ParsingSeparator sep = new ParsingSeparator(value, '|');
sep.addGroupingPair('[', ']');
sep.addGroupingPair('(', ')');
String activeValue = sep.next();
Formula count;
if (!sep.hasNext()) {
count = FormulaFactory.ONE;
} else {
count = FormulaFactory.getFormulaFor(activeValue);
if (!count.isValid()) {
return new ParseResult.Fail("Count in " + getTokenName() + " was not valid: " + count.toString(), context);
}
if (count.isStatic() && count.resolveStatic().doubleValue() <= 0) {
return new ParseResult.Fail("Count in " + getFullName() + " must be > 0", context);
}
activeValue = sep.next();
}
if (sep.hasNext()) {
return new ParseResult.Fail(getFullName() + " had too many pipe separated items: " + value, context);
}
ParseResult pr = checkSeparatorsAndNonEmpty(',', activeValue);
if (!pr.passed()) {
return pr;
}
List<CDOMReference<Skill>> refs = new ArrayList<>();
StringTokenizer tok = new StringTokenizer(activeValue, Constants.COMMA);
CDOMGroupRef<Skill> allRef = context.getReferenceContext().getCDOMAllReference(SKILL_CLASS);
Integer autoRank = null;
while (tok.hasMoreTokens()) {
String tokText = tok.nextToken();
if (Constants.LST_ALL.equals(tokText) || Constants.LST_ANY.equals(tokText)) {
refs.add(allRef);
} else {
if (Constants.LST_UNTRAINED.equals(tokText)) {
ObjectMatchingReference<Skill, Boolean> omr = new ObjectMatchingReference<>(tokText, SKILL_CLASS, allRef, ObjectKey.USE_UNTRAINED, Boolean.TRUE);
omr.returnIncludesNulls(true);
refs.add(omr);
} else if (Constants.LST_TRAINED.equals(tokText)) {
refs.add(new ObjectMatchingReference<>(tokText, SKILL_CLASS, allRef, ObjectKey.USE_UNTRAINED, Boolean.FALSE));
} else if (Constants.LST_EXCLUSIVE.equals(tokText)) {
refs.add(new ObjectMatchingReference<>(tokText, SKILL_CLASS, allRef, ObjectKey.EXCLUSIVE, Boolean.TRUE));
} else if (Constants.LST_NONEXCLUSIVE.equals(tokText) || Constants.LST_CROSS_CLASS.equals(tokText)) {
ObjectMatchingReference<Skill, Boolean> omr = new ObjectMatchingReference<>(tokText, SKILL_CLASS, allRef, ObjectKey.EXCLUSIVE, Boolean.FALSE);
omr.returnIncludesNulls(true);
refs.add(omr);
} else if (tokText.startsWith("AUTORANK=")) {
if (autoRank != null) {
return new ParseResult.Fail("Cannot have two " + "AUTORANK= items in " + getFullName() + ": " + value, context);
}
String rankString = tokText.substring(9);
try {
autoRank = Integer.decode(rankString);
if (autoRank <= 0) {
return new ParseResult.Fail("Expected AUTORANK= to be" + " greater than zero, found: " + autoRank, context);
}
} catch (NumberFormatException e) {
return new ParseResult.Fail("Expected AUTORANK= to have" + " an integer value, found: " + rankString, context);
}
} else {
CDOMReference<Skill> skref = TokenUtilities.getTypeOrPrimitive(context, SKILL_CLASS, tokText);
if (skref == null) {
return new ParseResult.Fail(" Error was encountered while parsing " + getFullName() + ": " + value + " had an invalid reference: " + tokText, context);
}
refs.add(skref);
}
}
}
if (refs.isEmpty()) {
return new ParseResult.Fail("Non-sensical " + getFullName() + ": Contains no skill reference: " + value, context);
}
ReferenceChoiceSet<Skill> rcs = new ReferenceChoiceSet<>(refs);
if (!rcs.getGroupingState().isValid()) {
return new ParseResult.Fail("Non-sensical " + getFullName() + ": Contains ANY and a specific reference: " + value, context);
}
ChoiceSet<Skill> cs = new ChoiceSet<>(getTokenName(), rcs, true);
PersistentTransitionChoice<Skill> tc = new ConcretePersistentTransitionChoice<>(cs, count);
// TODO This is a hack, to get this to work pre-CDOM
PCClass parent = (PCClass) obj.get(ObjectKey.TOKEN_PARENT);
ClassSkillChoiceActor actor = new ClassSkillChoiceActor(parent, autoRank);
tc.setChoiceActor(actor);
context.getObjectContext().addToList(obj, ListKey.ADD, tc);
return ParseResult.SUCCESS;
}
Aggregations