Search in sources :

Example 6 with ParsingSeparator

use of pcgen.base.text.ParsingSeparator in project pcgen by PCGen.

the class CastToken method parseTokenWithSeparator.

@Override
protected ParseResult parseTokenWithSeparator(LoadContext context, PCClassLevel level, String value) {
    context.getObjectContext().removeList(level, ListKey.CAST);
    ParsingSeparator sep = new ParsingSeparator(value, ',');
    sep.addGroupingPair('(', ')');
    while (sep.hasNext()) {
        String tok = sep.next();
        try {
            if (Integer.parseInt(tok) < 0) {
                return new ParseResult.Fail("Invalid Spell Count: " + tok + " is less than zero", context);
            }
        } catch (NumberFormatException e) {
        // OK, it must be a formula...
        }
        Formula formula = FormulaFactory.getFormulaFor(tok);
        if (!formula.isValid()) {
            return new ParseResult.Fail("Formula in " + getTokenName() + " was not valid: " + formula.toString(), context);
        }
        context.getObjectContext().addToList(level, ListKey.CAST, formula);
    }
    return ParseResult.SUCCESS;
}
Also used : Formula(pcgen.base.formula.Formula) ParsingSeparator(pcgen.base.text.ParsingSeparator)

Example 7 with ParsingSeparator

use of pcgen.base.text.ParsingSeparator in project pcgen by PCGen.

the class SpecialtyknownToken method parseTokenWithSeparator.

@Override
protected ParseResult parseTokenWithSeparator(LoadContext context, PCClassLevel level, String value) {
    context.getObjectContext().removeList(level, ListKey.SPECIALTYKNOWN);
    ParsingSeparator sep = new ParsingSeparator(value, ',');
    sep.addGroupingPair('(', ')');
    while (sep.hasNext()) {
        String tok = sep.next();
        try {
            if (Integer.parseInt(tok) < 0) {
                return new ParseResult.Fail("Invalid Spell Count: " + tok + " is less than zero", context);
            }
        } catch (NumberFormatException e) {
        // OK, it must be a formula...
        }
        Formula formula = FormulaFactory.getFormulaFor(tok);
        if (!formula.isValid()) {
            return new ParseResult.Fail("Formula in " + getTokenName() + " was not valid: " + formula.toString(), context);
        }
        context.getObjectContext().addToList(level, ListKey.SPECIALTYKNOWN, formula);
    }
    return ParseResult.SUCCESS;
}
Also used : Formula(pcgen.base.formula.Formula) ParsingSeparator(pcgen.base.text.ParsingSeparator)

Example 8 with ParsingSeparator

use of pcgen.base.text.ParsingSeparator 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;
}
Also used : AssociationKey(pcgen.cdom.enumeration.AssociationKey) ParseResult(pcgen.rules.persistence.token.ParseResult) ArrayList(java.util.ArrayList) Ungranted(pcgen.cdom.base.Ungranted) Spell(pcgen.core.spell.Spell) Formula(pcgen.base.formula.Formula) ParsingSeparator(pcgen.base.text.ParsingSeparator) CDOMObject(pcgen.cdom.base.CDOMObject) AssociatedPrereqObject(pcgen.cdom.base.AssociatedPrereqObject) DoubleKeyMap(pcgen.base.util.DoubleKeyMap) CDOMReference(pcgen.cdom.base.CDOMReference) Prerequisite(pcgen.core.prereq.Prerequisite)

Example 9 with ParsingSeparator

use of pcgen.base.text.ParsingSeparator 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;
}
Also used : ArrayList(java.util.ArrayList) ConcretePersistentTransitionChoice(pcgen.cdom.base.ConcretePersistentTransitionChoice) Formula(pcgen.base.formula.Formula) ObjectMatchingReference(pcgen.cdom.reference.ObjectMatchingReference) ParseResult(pcgen.rules.persistence.token.ParseResult) ReferenceChoiceSet(pcgen.cdom.choiceset.ReferenceChoiceSet) ChoiceSet(pcgen.cdom.base.ChoiceSet) PCClass(pcgen.core.PCClass) StringTokenizer(java.util.StringTokenizer) Skill(pcgen.core.Skill) ParsingSeparator(pcgen.base.text.ParsingSeparator) ClassSkillChoiceActor(pcgen.cdom.helper.ClassSkillChoiceActor) CDOMReference(pcgen.cdom.base.CDOMReference) ReferenceChoiceSet(pcgen.cdom.choiceset.ReferenceChoiceSet)

Example 10 with ParsingSeparator

use of pcgen.base.text.ParsingSeparator in project pcgen by PCGen.

the class ModifyOtherLst method parseTokenWithSeparator.

//MODIFYOTHER:EQUIPMENT|GROUP=Martial|EqCritRange|ADD|1
@Override
protected ParseResult parseTokenWithSeparator(LoadContext context, CDOMObject obj, String value) {
    if (obj instanceof Campaign) {
        return new ParseResult.Fail(getTokenName() + " may not be used in Campaign Files.  " + "Please use the Global Modifier file", context);
    }
    ParsingSeparator sep = new ParsingSeparator(value, '|');
    sep.addGroupingPair('[', ']');
    sep.addGroupingPair('(', ')');
    String scopeName = sep.next();
    /*
		 * Note lvs is implicitly defined as "not global" since the global scope
		 * is "" and thus would have failed the tests imposed by
		 * AbstractTokenWithSeparator
		 */
    final LegalScope lvs = context.getVariableContext().getScope(scopeName);
    if (lvs == null) {
        return new ParseResult.Fail(getTokenName() + " found illegal variable scope: " + scopeName + " as first argument: " + value, context);
    }
    if (!sep.hasNext()) {
        return new ParseResult.Fail(getTokenName() + " needed 2nd argument: " + value, context);
    }
    LoadContext subContext = context.dropIntoContext(lvs.getName());
    return continueParsing(subContext, obj, value, sep);
}
Also used : Campaign(pcgen.core.Campaign) ParsingSeparator(pcgen.base.text.ParsingSeparator) LegalScope(pcgen.base.formula.base.LegalScope) LoadContext(pcgen.rules.context.LoadContext)

Aggregations

ParsingSeparator (pcgen.base.text.ParsingSeparator)35 Formula (pcgen.base.formula.Formula)26 ParseResult (pcgen.rules.persistence.token.ParseResult)18 ArrayList (java.util.ArrayList)15 CDOMReference (pcgen.cdom.base.CDOMReference)10 ConcretePersistentTransitionChoice (pcgen.cdom.base.ConcretePersistentTransitionChoice)9 StringTokenizer (java.util.StringTokenizer)8 ChoiceSet (pcgen.cdom.base.ChoiceSet)7 ReferenceChoiceSet (pcgen.cdom.choiceset.ReferenceChoiceSet)6 PCClass (pcgen.core.PCClass)5 PersistenceLayerException (pcgen.persistence.PersistenceLayerException)5 Ungranted (pcgen.cdom.base.Ungranted)4 Prerequisite (pcgen.core.prereq.Prerequisite)4 Skill (pcgen.core.Skill)3 LegalScope (pcgen.base.formula.base.LegalScope)2 PrimitiveCollection (pcgen.cdom.base.PrimitiveCollection)2 AbilityRefChoiceSet (pcgen.cdom.choiceset.AbilityRefChoiceSet)2 CNAbility (pcgen.cdom.content.CNAbility)2 LevelCommandFactory (pcgen.cdom.content.LevelCommandFactory)2 Nature (pcgen.cdom.enumeration.Nature)2