Search in sources :

Example 21 with AssociatedPrereqObject

use of pcgen.cdom.base.AssociatedPrereqObject in project pcgen by PCGen.

the class ClassesToken method unparse.

@Override
public String[] unparse(LoadContext context, Spell spell) {
    DoubleKeyMapToList<Prerequisite, Integer, CDOMReference<ClassSpellList>> dkmtl = new DoubleKeyMapToList<>();
    List<String> list = new ArrayList<>();
    Changes<CDOMReference<ClassSpellList>> masterChanges = context.getListContext().getMasterListChanges(getTokenName(), spell, SPELLLIST_CLASS);
    if (masterChanges.includesGlobalClear()) {
        list.add(Constants.LST_DOT_CLEAR_ALL);
    }
    if (masterChanges.hasRemovedItems()) {
        for (CDOMReference<ClassSpellList> swl : masterChanges.getRemoved()) {
            AssociatedChanges<Spell> changes = context.getListContext().getChangesInMasterList(getTokenName(), spell, swl);
            MapToList<Spell, AssociatedPrereqObject> map = changes.getRemovedAssociations();
            if (map != null && !map.isEmpty()) {
                for (Spell added : map.getKeySet()) {
                    if (!spell.getLSTformat().equals(added.getLSTformat())) {
                        context.addWriteMessage("Spell " + getTokenName() + " token cannot remove another Spell " + "(must only remove itself)");
                        return null;
                    }
                    for (AssociatedPrereqObject assoc : map.getListFor(added)) {
                        List<Prerequisite> prereqs = assoc.getPrerequisiteList();
                        if (prereqs != null && !prereqs.isEmpty()) {
                            context.addWriteMessage("Incoming Remove " + "Edge to " + spell.getKeyName() + " had a " + "Prerequisite: " + prereqs.size());
                            return null;
                        }
                        dkmtl.addToListFor(null, -1, swl);
                    }
                }
            }
        }
    }
    for (CDOMReference<ClassSpellList> swl : masterChanges.getAdded()) {
        AssociatedChanges<Spell> changes = context.getListContext().getChangesInMasterList(getTokenName(), spell, swl);
        Collection<Spell> removedItems = changes.getRemoved();
        if (removedItems != null && !removedItems.isEmpty() || changes.includesGlobalClear()) {
            context.addWriteMessage(getTokenName() + " does not support .CLEAR.");
            return null;
        }
        MapToList<Spell, AssociatedPrereqObject> map = changes.getAddedAssociations();
        if (map != null && !map.isEmpty()) {
            for (Spell added : map.getKeySet()) {
                if (!spell.getLSTformat().equals(added.getLSTformat())) {
                    context.addWriteMessage("Spell " + getTokenName() + " token cannot allow another Spell " + "(must only allow itself)");
                    return null;
                }
                for (AssociatedPrereqObject assoc : map.getListFor(added)) {
                    List<Prerequisite> prereqs = assoc.getPrerequisiteList();
                    Prerequisite prereq;
                    if (prereqs == null || prereqs.isEmpty()) {
                        prereq = null;
                    } else if (prereqs.size() == 1) {
                        prereq = prereqs.get(0);
                    } else {
                        context.addWriteMessage("Incoming Edge to " + spell.getKeyName() + " had more than one " + "Prerequisite: " + prereqs.size());
                        return null;
                    }
                    Integer level = assoc.getAssociation(AssociationKey.SPELL_LEVEL);
                    if (level == null) {
                        context.addWriteMessage("Incoming Allows Edge to " + spell.getKeyName() + " had no Spell Level defined");
                        return null;
                    }
                    if (level.intValue() < 0) {
                        context.addWriteMessage("Incoming Allows Edge to " + spell.getKeyName() + " had invalid Level: " + level + ". Must be >= 0.");
                        return null;
                    }
                    dkmtl.addToListFor(prereq, level, swl);
                }
            }
        }
    }
    if (dkmtl.isEmpty()) {
        if (list.isEmpty()) {
            // Legal if no CLASSES was present in the Spell
            return null;
        } else {
            return list.toArray(new String[list.size()]);
        }
    }
    PrerequisiteWriter prereqWriter = new PrerequisiteWriter();
    SortedSet<CDOMReference<ClassSpellList>> set = new TreeSet<>(ReferenceUtilities.REFERENCE_SORTER);
    SortedSet<Integer> levelSet = new TreeSet<>();
    for (Prerequisite prereq : dkmtl.getKeySet()) {
        StringBuilder sb = new StringBuilder();
        boolean needPipe = false;
        levelSet.clear();
        levelSet.addAll(dkmtl.getSecondaryKeySet(prereq));
        for (Integer i : levelSet) {
            set.clear();
            set.addAll(dkmtl.getListFor(prereq, i));
            if (needPipe) {
                sb.append(Constants.PIPE);
            }
            sb.append(ReferenceUtilities.joinLstFormat(set, Constants.COMMA));
            sb.append('=').append(i);
            needPipe = true;
        }
        if (prereq != null) {
            sb.append('[');
            StringWriter swriter = new StringWriter();
            try {
                prereqWriter.write(swriter, prereq);
            } catch (PersistenceLayerException e) {
                context.addWriteMessage("Error writing Prerequisite: " + e);
                return null;
            }
            sb.append(swriter.toString());
            sb.append(']');
        }
        list.add(sb.toString());
    }
    return list.toArray(new String[list.size()]);
}
Also used : PrerequisiteWriter(pcgen.persistence.lst.output.prereq.PrerequisiteWriter) ArrayList(java.util.ArrayList) Spell(pcgen.core.spell.Spell) StringWriter(java.io.StringWriter) TreeSet(java.util.TreeSet) AssociatedPrereqObject(pcgen.cdom.base.AssociatedPrereqObject) ClassSpellList(pcgen.cdom.list.ClassSpellList) DoubleKeyMapToList(pcgen.base.util.DoubleKeyMapToList) PersistenceLayerException(pcgen.persistence.PersistenceLayerException) CDOMReference(pcgen.cdom.base.CDOMReference) Prerequisite(pcgen.core.prereq.Prerequisite)

Example 22 with AssociatedPrereqObject

use of pcgen.cdom.base.AssociatedPrereqObject in project pcgen by PCGen.

the class DomainsToken method unparse.

@Override
public String[] unparse(LoadContext context, Deity deity) {
    CDOMReference<DomainList> dl = Deity.DOMAINLIST;
    AssociatedChanges<CDOMReference<Domain>> changes = context.getListContext().getChangesInList(getTokenName(), deity, dl);
    List<String> list = new ArrayList<>();
    Collection<CDOMReference<Domain>> removedItems = changes.getRemoved();
    if (changes.includesGlobalClear()) {
        if (removedItems != null && !removedItems.isEmpty()) {
            context.addWriteMessage("Non-sensical relationship in " + getTokenName() + ": global .CLEAR and local .CLEAR. performed");
            return null;
        }
        list.add(Constants.LST_DOT_CLEAR);
    } else if (removedItems != null && !removedItems.isEmpty()) {
        list.add(Constants.LST_DOT_CLEAR_DOT + ReferenceUtilities.joinLstFormat(removedItems, ",.CLEAR.", true));
    }
    MapToList<CDOMReference<Domain>, AssociatedPrereqObject> mtl = changes.getAddedAssociations();
    if (mtl != null && !mtl.isEmpty()) {
        MapToList<Set<Prerequisite>, CDOMReference<Domain>> m = new HashMapToList<>();
        for (CDOMReference<Domain> ab : mtl.getKeySet()) {
            for (AssociatedPrereqObject assoc : mtl.getListFor(ab)) {
                m.addToListFor(new HashSet<>(assoc.getPrerequisiteList()), ab);
            }
        }
        Set<String> set = new TreeSet<>();
        for (Set<Prerequisite> prereqs : m.getKeySet()) {
            Set<CDOMReference<Domain>> domainSet = new TreeSet<>(ReferenceUtilities.REFERENCE_SORTER);
            domainSet.addAll(m.getListFor(prereqs));
            StringBuilder sb = new StringBuilder(ReferenceUtilities.joinLstFormat(domainSet, Constants.COMMA, true));
            if (prereqs != null && !prereqs.isEmpty()) {
                sb.append(Constants.PIPE);
                sb.append(getPrerequisiteString(context, prereqs));
            }
            set.add(sb.toString());
        }
        list.addAll(set);
    }
    if (list.isEmpty()) {
        return null;
    }
    return list.toArray(new String[list.size()]);
}
Also used : Set(java.util.Set) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) ArrayList(java.util.ArrayList) DomainList(pcgen.cdom.list.DomainList) HashMapToList(pcgen.base.util.HashMapToList) TreeSet(java.util.TreeSet) Domain(pcgen.core.Domain) CDOMReference(pcgen.cdom.base.CDOMReference) AssociatedPrereqObject(pcgen.cdom.base.AssociatedPrereqObject) Prerequisite(pcgen.core.prereq.Prerequisite)

Example 23 with AssociatedPrereqObject

use of pcgen.cdom.base.AssociatedPrereqObject in project pcgen by PCGen.

the class DomainsToken method parseTokenWithSeparator.

@Override
protected ParseResult parseTokenWithSeparator(LoadContext context, Deity deity, String value) {
    StringTokenizer pipeTok = new StringTokenizer(value, Constants.PIPE);
    StringTokenizer commaTok = new StringTokenizer(pipeTok.nextToken(), Constants.COMMA);
    CDOMReference<DomainList> dl = Deity.DOMAINLIST;
    ArrayList<AssociatedPrereqObject> proList = new ArrayList<>();
    boolean first = true;
    boolean foundAll = false;
    boolean foundOther = false;
    boolean foundClear = false;
    while (commaTok.hasMoreTokens()) {
        String tokString = commaTok.nextToken();
        if (looksLikeAPrerequisite(tokString)) {
            return new ParseResult.Fail("Invalid " + getTokenName() + ": PRExxx was comma delimited : " + value, context);
        }
        if (Constants.LST_DOT_CLEAR.equals(tokString)) {
            if (!first) {
                return new ParseResult.Fail("  Non-sensical " + getTokenName() + ": .CLEAR was not the first list item: " + value, context);
            }
            context.getListContext().removeAllFromList(getTokenName(), deity, dl);
            foundClear = true;
        } else if (tokString.startsWith(Constants.LST_DOT_CLEAR_DOT)) {
            CDOMReference<Domain> ref;
            String clearText = tokString.substring(7);
            if (Constants.LST_ALL.equals(clearText) || Constants.LST_ANY.equals(clearText)) {
                ref = context.getReferenceContext().getCDOMAllReference(DOMAIN_CLASS);
            } else {
                ref = context.getReferenceContext().getCDOMReference(DOMAIN_CLASS, clearText);
            }
            context.getListContext().removeFromList(getTokenName(), deity, dl, ref);
            foundClear = true;
        } else if (Constants.LST_ALL.equals(tokString) || Constants.LST_ANY.equals(tokString)) {
            CDOMGroupRef<Domain> ref = context.getReferenceContext().getCDOMAllReference(DOMAIN_CLASS);
            proList.add(context.getListContext().addToList(getTokenName(), deity, dl, ref));
            foundAll = true;
        } else {
            CDOMSingleRef<Domain> ref = context.getReferenceContext().getCDOMReference(DOMAIN_CLASS, tokString);
            proList.add(context.getListContext().addToList(getTokenName(), deity, dl, ref));
            foundOther = true;
        }
        first = false;
    }
    if (foundAll && foundOther) {
        return new ParseResult.Fail("Non-sensical " + getTokenName() + ": Contains ALL and a specific reference: " + value, context);
    }
    while (pipeTok.hasMoreTokens()) {
        if (foundClear) {
            return new ParseResult.Fail("Cannot use PREREQs when using .CLEAR or .CLEAR. in " + getTokenName(), context);
        }
        String tokString = pipeTok.nextToken();
        Prerequisite prereq = getPrerequisite(tokString);
        if (prereq == null) {
            return new ParseResult.Fail("   (Did you put items after the " + "PRExxx tags in " + getTokenName() + ":?)", context);
        }
        for (AssociatedPrereqObject ao : proList) {
            ao.addPrerequisite(prereq);
        }
    }
    return ParseResult.SUCCESS;
}
Also used : ArrayList(java.util.ArrayList) DomainList(pcgen.cdom.list.DomainList) StringTokenizer(java.util.StringTokenizer) Domain(pcgen.core.Domain) CDOMReference(pcgen.cdom.base.CDOMReference) AssociatedPrereqObject(pcgen.cdom.base.AssociatedPrereqObject) Prerequisite(pcgen.core.prereq.Prerequisite)

Example 24 with AssociatedPrereqObject

use of pcgen.cdom.base.AssociatedPrereqObject in project pcgen by PCGen.

the class LoadContextTest method testCloneInMasterListsAssoc.

/**
	 * Test method for {@link pcgen.rules.context.LoadContext#cloneInMasterLists(pcgen.cdom.base.CDOMObject, java.lang.String)}.
	 * Verify that associations from other objects to the object being cloned 
	 * are copied over. 
	 */
public final void testCloneInMasterListsAssoc() {
    final LoadContext context = Globals.getContext();
    FactKey.getConstant("ClassType", new StringManager());
    FactKey.getConstant("SpellType", new StringManager());
    Spell testSpell = TestHelper.makeSpell("LoadContextTest");
    PCClass wiz = TestHelper.makeClass("Wizard");
    CDOMReference<ClassSpellList> ref = TokenUtilities.getTypeOrPrimitive(context, ClassSpellList.class, wiz.getKeyName());
    AssociatedPrereqObject edge = context.getListContext().addToMasterList("CLASSES", testSpell, ref, testSpell);
    edge.setAssociation(AssociationKey.SPELL_LEVEL, 1);
    context.getReferenceContext().buildDerivedObjects();
    assertTrue(context.getReferenceContext().resolveReferences(null));
    context.commit();
    Spell newSpell = context.performCopy(testSpell, "New Spell");
    context.commit();
    assertEquals("Old spell name incorrect", "LoadContextTest", testSpell.getDisplayName());
    assertEquals("New spell name incorrect", "New Spell", newSpell.getDisplayName());
    // Check associations
    MasterListInterface masterLists = SettingsHandler.getGame().getMasterLists();
    Collection<AssociatedPrereqObject> assoc = masterLists.getAssociations(ref, testSpell);
    assertEquals("Incorrect size of assoc list for orig spell", 1, assoc.size());
    AssociatedPrereqObject apo = assoc.iterator().next();
    assertEquals("Incorrect level", 1, apo.getAssociation(AssociationKey.SPELL_LEVEL).intValue());
    assoc = masterLists.getAssociations(ref, newSpell);
    assertEquals("Incorrect size of assoc list for new spell", 1, assoc.size());
    apo = assoc.iterator().next();
    assertEquals("Incorrect level", 1, apo.getAssociation(AssociationKey.SPELL_LEVEL).intValue());
}
Also used : MasterListInterface(pcgen.cdom.base.MasterListInterface) ClassSpellList(pcgen.cdom.list.ClassSpellList) PCClass(pcgen.core.PCClass) Spell(pcgen.core.spell.Spell) StringManager(pcgen.base.format.StringManager) AssociatedPrereqObject(pcgen.cdom.base.AssociatedPrereqObject)

Example 25 with AssociatedPrereqObject

use of pcgen.cdom.base.AssociatedPrereqObject in project pcgen by PCGen.

the class MonccskillToken method parseTokenWithSeparator.

@Override
protected ParseResult parseTokenWithSeparator(LoadContext context, Race race, String value) {
    boolean firstToken = true;
    boolean foundAny = false;
    boolean foundOther = false;
    StringTokenizer tok = new StringTokenizer(value, Constants.PIPE);
    CDOMGroupRef<ClassSkillList> monsterList = context.getReferenceContext().getCDOMTypeReference(ClassSkillList.class, "Monster");
    while (tok.hasMoreTokens()) {
        String tokText = tok.nextToken();
        if (Constants.LST_DOT_CLEAR.equals(tokText)) {
            if (!firstToken) {
                return new ParseResult.Fail("Non-sensical situation was " + "encountered while parsing " + getTokenName() + ": When used, .CLEAR must be the first argument", context);
            }
            context.getListContext().removeAllFromList(getTokenName(), race, monsterList);
        } else if (tokText.startsWith(Constants.LST_DOT_CLEAR_DOT)) {
            CDOMReference<Skill> skill;
            String clearText = tokText.substring(7);
            if (Constants.LST_ALL.equals(clearText)) {
                skill = context.getReferenceContext().getCDOMAllReference(SKILL_CLASS);
            } else {
                skill = getSkillReference(context, clearText);
            }
            if (skill == null) {
                return new ParseResult.Fail("  Error was encountered while parsing " + getTokenName(), context);
            }
            context.getListContext().removeFromList(getTokenName(), race, monsterList, skill);
        } else {
            /*
				 * Note this is done one-by-one, because .CLEAR. token type
				 * needs to be able to perform the unlink. That could be
				 * changed, but the increase in complexity isn't worth it.
				 * (Changing it to a grouping object that didn't place links in
				 * the graph would also make it harder to trace the source of
				 * class skills, etc.)
				 */
            CDOMReference<Skill> skill;
            if (Constants.LST_ALL.equals(tokText)) {
                foundAny = true;
                skill = context.getReferenceContext().getCDOMAllReference(SKILL_CLASS);
            } else {
                foundOther = true;
                skill = getSkillReference(context, tokText);
            }
            if (skill == null) {
                return new ParseResult.Fail("  Error was encountered while parsing " + getTokenName(), context);
            }
            AssociatedPrereqObject apo = context.getListContext().addToList(getTokenName(), race, monsterList, skill);
            apo.setAssociation(AssociationKey.SKILL_COST, SkillCost.CROSS_CLASS);
        }
        firstToken = false;
    }
    if (foundAny && foundOther) {
        return new ParseResult.Fail("Non-sensical " + getTokenName() + ": Contains ANY and a specific reference: " + value, context);
    }
    return ParseResult.SUCCESS;
}
Also used : StringTokenizer(java.util.StringTokenizer) ParseResult(pcgen.rules.persistence.token.ParseResult) ClassSkillList(pcgen.cdom.list.ClassSkillList) CDOMReference(pcgen.cdom.base.CDOMReference) AssociatedPrereqObject(pcgen.cdom.base.AssociatedPrereqObject)

Aggregations

AssociatedPrereqObject (pcgen.cdom.base.AssociatedPrereqObject)50 CDOMReference (pcgen.cdom.base.CDOMReference)34 ArrayList (java.util.ArrayList)18 Prerequisite (pcgen.core.prereq.Prerequisite)18 Spell (pcgen.core.spell.Spell)14 StringTokenizer (java.util.StringTokenizer)11 TreeSet (java.util.TreeSet)10 Domain (pcgen.core.Domain)8 CDOMObject (pcgen.cdom.base.CDOMObject)7 ClassSpellList (pcgen.cdom.list.ClassSpellList)7 CDOMList (pcgen.cdom.base.CDOMList)6 PersistenceLayerException (pcgen.persistence.PersistenceLayerException)6 ParseResult (pcgen.rules.persistence.token.ParseResult)6 HashSet (java.util.HashSet)5 MasterListInterface (pcgen.cdom.base.MasterListInterface)5 AssociationKey (pcgen.cdom.enumeration.AssociationKey)5 ClassSkillList (pcgen.cdom.list.ClassSkillList)5 DomainSpellList (pcgen.cdom.list.DomainSpellList)5 StringWriter (java.io.StringWriter)4 PCClass (pcgen.core.PCClass)4