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()]);
}
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()]);
}
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;
}
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());
}
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;
}
Aggregations