use of pcgen.cdom.enumeration.Nature in project pcgen by PCGen.
the class AbilityLst method unparse.
@Override
public String[] unparse(LoadContext context, CDOMObject obj) {
Collection<CDOMReference<? extends CDOMList<?>>> changedLists = context.getListContext().getChangedLists(obj, AbilityList.class);
Changes<ListKey<ChooseSelectionActor<?>>> actors = context.getObjectContext().getListChanges(obj, ListKey.GA_CAKEYS);
Set<String> returnSet = new TreeSet<>();
TripleKeyMapToList<Nature, CDOMSingleRef<AbilityCategory>, List<Prerequisite>, CDOMReference<Ability>> m = new TripleKeyMapToList<>();
TripleKeyMapToList<Nature, CDOMSingleRef<AbilityCategory>, List<Prerequisite>, CDOMReference<Ability>> clear = new TripleKeyMapToList<>();
Changes<ChooseSelectionActor<?>> listChanges = context.getObjectContext().getListChanges(obj, ListKey.NEW_CHOOSE_ACTOR);
Collection<ChooseSelectionActor<?>> listAdded = listChanges.getAdded();
if (listAdded != null && !listAdded.isEmpty()) {
for (ChooseSelectionActor<?> csa : listAdded) {
if (csa.getSource().equals(getTokenName())) {
try {
AbilitySelector as = (AbilitySelector) csa;
StringBuilder sb = new StringBuilder();
sb.append(as.getAbilityCategory().getLSTformat(false)).append(Constants.PIPE);
sb.append(as.getNature()).append(Constants.PIPE);
sb.append(as.getLstFormat());
returnSet.add(sb.toString());
} catch (PersistenceLayerException e) {
context.addWriteMessage(getTokenName() + " encountered error: " + e.getMessage());
return null;
}
}
}
}
for (CDOMReference ref : changedLists) {
AssociatedChanges<CDOMReference<Ability>> changes = context.getListContext().getChangesInList(getTokenName(), obj, ref);
if (changes.includesGlobalClear()) {
CDOMDirectSingleRef<AbilityList> dr = (CDOMDirectSingleRef<AbilityList>) ref;
AbilityList al = dr.get();
StringBuilder sb = new StringBuilder();
sb.append(al.getCategory().getLSTformat(false)).append(Constants.PIPE);
sb.append(al.getNature()).append(Constants.PIPE);
sb.append(Constants.LST_DOT_CLEAR);
returnSet.add(sb.toString());
}
MapToList<CDOMReference<Ability>, AssociatedPrereqObject> mtl = changes.getAddedAssociations();
if (mtl != null) {
for (CDOMReference<Ability> ab : mtl.getKeySet()) {
for (AssociatedPrereqObject assoc : mtl.getListFor(ab)) {
Nature nature = assoc.getAssociation(AssociationKey.NATURE);
CDOMSingleRef<AbilityCategory> cat = assoc.getAssociation(AssociationKey.CATEGORY);
m.addToListFor(nature, cat, assoc.getPrerequisiteList(), ab);
}
}
}
mtl = changes.getRemovedAssociations();
if (mtl != null) {
for (CDOMReference<Ability> ab : mtl.getKeySet()) {
for (AssociatedPrereqObject assoc : mtl.getListFor(ab)) {
Nature nature = assoc.getAssociation(AssociationKey.NATURE);
CDOMSingleRef<AbilityCategory> cat = assoc.getAssociation(AssociationKey.CATEGORY);
clear.addToListFor(nature, cat, assoc.getPrerequisiteList(), ab);
}
}
}
}
for (Nature nature : m.getKeySet()) {
for (CDOMSingleRef<AbilityCategory> category : m.getSecondaryKeySet(nature)) {
for (List<Prerequisite> prereqs : m.getTertiaryKeySet(nature, category)) {
StringBuilder sb = new StringBuilder();
sb.append(category.getLSTformat(false)).append(Constants.PIPE);
sb.append(nature);
List<CDOMReference<Ability>> clearList = clear.removeListFor(nature, category, prereqs);
if (clearList != null && !clearList.isEmpty()) {
sb.append(Constants.PIPE);
sb.append(Constants.LST_DOT_CLEAR_DOT);
sb.append(ReferenceUtilities.joinLstFormat(clearList, Constants.PIPE + Constants.LST_DOT_CLEAR_DOT));
}
sb.append(Constants.PIPE);
sb.append(ReferenceUtilities.joinLstFormat(m.getListFor(nature, category, prereqs), Constants.PIPE));
if (prereqs != null && !prereqs.isEmpty()) {
sb.append(Constants.PIPE);
sb.append(getPrerequisiteString(context, prereqs));
}
returnSet.add(sb.toString());
}
}
}
for (Nature nature : clear.getKeySet()) {
for (CDOMSingleRef<AbilityCategory> category : clear.getSecondaryKeySet(nature)) {
for (List<Prerequisite> prereqs : clear.getTertiaryKeySet(nature, category)) {
StringBuilder sb = new StringBuilder();
sb.append(category.getLSTformat(false)).append(Constants.PIPE);
sb.append(nature).append(Constants.PIPE).append(Constants.LST_DOT_CLEAR_DOT);
sb.append(ReferenceUtilities.joinLstFormat(clear.getListFor(nature, category, prereqs), Constants.PIPE + Constants.LST_DOT_CLEAR_DOT));
if (prereqs != null && !prereqs.isEmpty()) {
sb.append(Constants.PIPE);
sb.append(getPrerequisiteString(context, prereqs));
}
returnSet.add(sb.toString());
}
}
}
Collection<ListKey<ChooseSelectionActor<?>>> addedActors = actors.getAdded();
if (addedActors != null) {
for (ListKey<ChooseSelectionActor<?>> lk : addedActors) {
Changes<ChooseSelectionActor<?>> cras = context.getObjectContext().getListChanges(obj, lk);
for (ChooseSelectionActor<?> cra : cras.getAdded()) {
if (getTokenName().equals(cra.getSource())) {
try {
AbilityTargetSelector ats = (AbilityTargetSelector) cra;
StringBuilder sb = new StringBuilder();
sb.append(ats.getAbilityCategory().getLSTformat(false)).append(Constants.PIPE);
sb.append(ats.getNature()).append(Constants.PIPE).append(cra.getLstFormat());
List<Prerequisite> prereqs = ats.getPrerequisiteList();
if (prereqs != null && !prereqs.isEmpty()) {
sb.append(Constants.PIPE);
sb.append(getPrerequisiteString(context, prereqs));
}
returnSet.add(sb.toString());
} catch (PersistenceLayerException e) {
context.addWriteMessage(getTokenName() + " encountered error: " + e.getMessage());
return null;
}
}
}
}
}
if (returnSet.isEmpty()) {
return null;
}
return returnSet.toArray(new String[returnSet.size()]);
}
use of pcgen.cdom.enumeration.Nature in project pcgen by PCGen.
the class AbilityLst 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 tok = new StringTokenizer(value, Constants.PIPE);
String cat = tok.nextToken();
CDOMSingleRef<AbilityCategory> acRef = context.getReferenceContext().getCDOMReference(ABILITY_CATEGORY_CLASS, cat);
if (!tok.hasMoreTokens()) {
return new ParseResult.Fail(getTokenName() + " must have a Nature, " + "Format is: CATEGORY|NATURE|AbilityName: " + value, context);
}
final String natureKey = tok.nextToken();
Nature nature;
try {
nature = Nature.valueOf(natureKey);
} catch (IllegalArgumentException iae) {
return new ParseResult.Fail(getTokenName() + " refers to invalid Ability Nature: " + natureKey, context);
}
if (Nature.ANY.equals(nature)) {
return new ParseResult.Fail(getTokenName() + " refers to ANY Ability Nature, cannot be used in " + getTokenName() + ": " + value, context);
}
if (!tok.hasMoreTokens()) {
return new ParseResult.Fail(getTokenName() + " must have abilities, Format is: " + "CATEGORY|NATURE|AbilityName: " + value, context);
}
String token = tok.nextToken();
if (looksLikeAPrerequisite(token)) {
return new ParseResult.Fail("Cannot have only PRExxx subtoken in " + getTokenName() + ": " + value, context);
}
String lkString = "GA_CA_" + cat + '_' + natureKey;
ListKey glk = ListKey.getKeyFor(ChooseSelectionActor.class, lkString);
ListKey<ChooseSelectionActor<?>> lk = glk;
ArrayList<PrereqObject> edgeList = new ArrayList<>();
CDOMReference<AbilityList> abilList = AbilityList.getAbilityListReference(acRef, nature);
boolean first = true;
boolean removed = false;
ReferenceManufacturer<Ability> rm = context.getReferenceContext().getManufacturer(ABILITY_CLASS, ABILITY_CATEGORY_CLASS, cat);
if (rm == null) {
return new ParseResult.Fail("Could not get Reference Manufacturer for Category: " + cat, context);
}
boolean prereqsAllowed = true;
while (true) {
if (Constants.LST_DOT_CLEAR.equals(token)) {
if (!first) {
return new ParseResult.Fail(" Non-sensical " + getTokenName() + ": .CLEAR was not the first list item: " + value, context);
}
context.getListContext().removeAllFromList(getTokenName(), obj, abilList);
context.getObjectContext().removeFromList(obj, ListKey.GA_CAKEYS, lk);
context.getObjectContext().removeList(obj, lk);
removed = true;
} else if (token.startsWith(Constants.LST_DOT_CLEAR_DOT)) {
String clearText = token.substring(7);
CDOMReference<Ability> ref = TokenUtilities.getTypeOrPrimitive(rm, clearText);
if (ref == null) {
return ParseResult.INTERNAL_ERROR;
}
AssociatedPrereqObject assoc = context.getListContext().removeFromList(getTokenName(), obj, abilList, ref);
assoc.setAssociation(AssociationKey.NATURE, nature);
assoc.setAssociation(AssociationKey.CATEGORY, acRef);
removed = true;
} else if (Constants.LST_PERCENT_LIST.equals(token)) {
prereqsAllowed = false;
AbilitySelector as = new AbilitySelector(getTokenName(), acRef, nature);
context.getObjectContext().addToList(obj, ListKey.NEW_CHOOSE_ACTOR, as);
} else {
CDOMReference<Ability> ability = TokenUtilities.getTypeOrPrimitive(rm, token);
if (ability == null) {
return ParseResult.INTERNAL_ERROR;
}
ability.setRequiresTarget(true);
boolean loadList = true;
List<String> choices = null;
if (token.indexOf('(') != -1) {
choices = new ArrayList<>();
AbilityUtilities.getUndecoratedName(token, choices);
if (choices.size() == 1) {
if (Constants.LST_PERCENT_LIST.equals(choices.get(0)) && (ability instanceof CDOMSingleRef)) {
CDOMSingleRef<Ability> ref = (CDOMSingleRef<Ability>) ability;
AbilityTargetSelector ats = new AbilityTargetSelector(getTokenName(), acRef, ref, nature);
context.getObjectContext().addToList(obj, ListKey.GA_CAKEYS, lk);
context.getObjectContext().addToList(obj, lk, ats);
edgeList.add(ats);
loadList = false;
}
}
}
if (loadList) {
AssociatedPrereqObject assoc = context.getListContext().addToList(getTokenName(), obj, abilList, ability);
assoc.setAssociation(AssociationKey.NATURE, nature);
assoc.setAssociation(AssociationKey.CATEGORY, acRef);
if (choices != null) {
assoc.setAssociation(AssociationKey.ASSOC_CHOICES, choices);
}
edgeList.add(assoc);
}
}
if (!tok.hasMoreTokens()) {
// No prereqs, so we're done
return ParseResult.SUCCESS;
}
first = false;
token = tok.nextToken();
if (looksLikeAPrerequisite(token)) {
break;
}
}
if (removed || !prereqsAllowed) {
return new ParseResult.Fail("Cannot use PREREQs when using .CLEAR, .CLEAR., or %LIST in " + getTokenName(), context);
}
while (true) {
Prerequisite prereq = getPrerequisite(token);
if (prereq == null) {
return new ParseResult.Fail(" (Did you put feats after the " + "PRExxx tags in " + getTokenName() + ":?)", context);
}
for (PrereqObject edge : edgeList) {
edge.addPrerequisite(prereq);
}
if (!tok.hasMoreTokens()) {
break;
}
token = tok.nextToken();
}
return ParseResult.SUCCESS;
}
use of pcgen.cdom.enumeration.Nature in project pcgen by PCGen.
the class AbilityToken method parseNonEmptyToken.
@Override
protected ParseResult parseNonEmptyToken(LoadContext context, CDOMObject obj, String value) {
if (isEmpty(value)) {
return new ParseResult.Fail("Value in " + getFullName() + " may not be empty", context);
}
ParsingSeparator sep = new ParsingSeparator(value, '|');
sep.addGroupingPair('[', ']');
sep.addGroupingPair('(', ')');
String first = sep.next();
if (!sep.hasNext()) {
return new ParseResult.Fail("Syntax of ADD:" + getTokenName() + " requires 3 to 4 |: " + value, context);
}
String second = sep.next();
if (!sep.hasNext()) {
return new ParseResult.Fail("Syntax of ADD:" + getTokenName() + " requires a minimum of three | : " + value, context);
}
String third = sep.next();
Formula count;
if (sep.hasNext()) {
count = FormulaFactory.getFormulaFor(first);
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);
}
first = second;
second = third;
third = sep.next();
} else {
count = FormulaFactory.ONE;
}
if (sep.hasNext()) {
return new ParseResult.Fail("Syntax of ADD:" + getTokenName() + " has max of four | when a count is not present: " + value, context);
}
CDOMSingleRef<AbilityCategory> acRef = context.getReferenceContext().getCDOMReference(ABILITY_CATEGORY_CLASS, first);
Nature nature = Nature.valueOf(second);
if (nature == null) {
return new ParseResult.Fail(getFullName() + ": Invalid ability nature: " + second, context);
}
if (Nature.ANY.equals(nature)) {
return new ParseResult.Fail(getTokenName() + " refers to ANY Ability Nature, cannot be used in " + getTokenName() + ": " + value);
}
if (Nature.AUTOMATIC.equals(nature)) {
return new ParseResult.Fail(getTokenName() + " refers to AUTOMATIC Ability Nature, cannot be used in " + getTokenName() + ": " + value, context);
}
ParseResult pr = checkSeparatorsAndNonEmpty(',', third);
if (!pr.passed()) {
return pr;
}
List<CDOMReference<Ability>> refs = new ArrayList<>();
ParsingSeparator tok = new ParsingSeparator(third, ',');
tok.addGroupingPair('[', ']');
tok.addGroupingPair('(', ')');
boolean allowStack = false;
int dupChoices = 0;
ReferenceManufacturer<Ability> rm = context.getReferenceContext().getManufacturer(ABILITY_CLASS, ABILITY_CATEGORY_CLASS, first);
if (rm == null) {
return new ParseResult.Fail("Could not get Reference Manufacturer for Category: " + first, context);
}
while (tok.hasNext()) {
CDOMReference<Ability> ab;
String token = tok.next();
if ("STACKS".equals(token)) {
if (allowStack) {
return new ParseResult.Fail(getFullName() + " found second stacking specification in value: " + value, context);
}
allowStack = true;
continue;
} else if (token.startsWith("STACKS=")) {
if (allowStack) {
return new ParseResult.Fail(getFullName() + " found second stacking specification in value: " + value, context);
}
allowStack = true;
try {
dupChoices = Integer.parseInt(token.substring(7));
} catch (NumberFormatException nfe) {
return new ParseResult.Fail("Invalid Stack number in " + getFullName() + ": " + value, context);
}
if (dupChoices <= 0) {
return new ParseResult.Fail("Invalid (less than 1) Stack number in " + getFullName() + ": " + value, context);
}
continue;
} else {
if (Constants.LST_ALL.equals(token)) {
ab = rm.getAllReference();
} else {
ab = TokenUtilities.getTypeOrPrimitive(rm, token);
}
}
if (ab == null) {
return new ParseResult.Fail(" Error was encountered while parsing " + getTokenName() + ": " + value + " had an invalid reference: " + token, context);
}
refs.add(ab);
}
if (refs.isEmpty()) {
return new ParseResult.Fail("Non-sensical " + getFullName() + ": Contains no ability reference: " + value, context);
}
AbilityRefChoiceSet rcs = new AbilityRefChoiceSet(acRef, refs, nature);
if (!rcs.getGroupingState().isValid()) {
return new ParseResult.Fail("Non-sensical " + getFullName() + ": Contains ANY and a specific reference: " + value, context);
}
AbilityChoiceSet cs = new AbilityChoiceSet(getTokenName(), rcs);
StringBuilder title = new StringBuilder(50);
if (!Nature.NORMAL.equals(nature)) {
title.append(nature.toString());
title.append(' ');
}
title.append(first);
title.append(" Choice");
cs.setTitle(title.toString());
PersistentTransitionChoice<CNAbilitySelection> tc = new ConcretePersistentTransitionChoice<>(cs, count);
context.getObjectContext().addToList(obj, ListKey.ADD, tc);
tc.allowStack(allowStack);
if (dupChoices != 0) {
tc.setStackLimit(dupChoices);
}
tc.setChoiceActor(this);
return ParseResult.SUCCESS;
}
use of pcgen.cdom.enumeration.Nature in project pcgen by PCGen.
the class CategorizedAbilityFacet method copyContents.
/**
* Copies the contents of the CategorizedAbilityFacet from one Player
* Character to another Player Character, based on the given CharIDs
* representing those Player Characters.
*
* This is a method in CategorizedAbilityFacet in order to avoid exposing
* the mutable Map object to other classes. This should not be inlined, as
* the Map is internal information to CategorizedAbilityFacet and should not
* be exposed to other classes.
*
* Note also the copy is a one-time event and no references are maintained
* between the Player Characters represented by the given CharIDs (meaning
* once this copy takes place, any change to the CategorizedAbilityFacet of
* one Player Character will only impact the Player Character where the
* CategorizedAbilityFacet was changed).
*
* @param source
* The CharID representing the Player Character from which the
* information should be copied
* @param copy
* The CharID representing the Player Character to which the
* information should be copied
*/
@Override
public void copyContents(CharID source, CharID copy) {
Map<Category<Ability>, Map<Nature, Set<Ability>>> map = getCachedMap(source);
if (map != null) {
for (Entry<Category<Ability>, Map<Nature, Set<Ability>>> me : map.entrySet()) {
Category<Ability> cat = me.getKey();
for (Entry<Nature, Set<Ability>> nme : me.getValue().entrySet()) {
Nature nat = nme.getKey();
ensureCachedSet(copy, cat, nat);
getCachedSet(copy, cat, nat).addAll(nme.getValue());
}
}
}
}
use of pcgen.cdom.enumeration.Nature in project pcgen by PCGen.
the class PCGVer2Parser method parseAbilityLine.
/*
* ###############################################################
* Character Ability methods
* ###############################################################
*/
private void parseAbilityLine(final String line) {
final PCGTokenizer tokens;
try {
tokens = new PCGTokenizer(line);
} catch (PCGParseException pcgpex) {
final String msg = LanguageBundle.getFormattedString(//$NON-NLS-1$
"Warnings.PCGenParser.IllegalAbility", line, pcgpex.getMessage());
warnings.add(msg);
return;
}
AbilityCategory category = null;
Nature nature = Nature.NORMAL;
String abilityCat = null;
Ability ability = null;
String missingCat = null;
final Iterator<PCGElement> it = tokens.getElements().iterator();
// the first element defines the AbilityCategory key name
if (it.hasNext()) {
final PCGElement element = it.next();
final String categoryKey = EntityEncoder.decode(element.getText());
category = SettingsHandler.getGame().getAbilityCategory(categoryKey);
if (category == null) {
missingCat = categoryKey;
}
}
// The next element will be the nature
if (it.hasNext()) {
final PCGElement element = it.next();
final String natureKey = EntityEncoder.decode(element.getText());
nature = Nature.valueOf(natureKey);
}
// The next element will be the ability's innate category
if (it.hasNext()) {
final PCGElement element = it.next();
abilityCat = EntityEncoder.decode(element.getText());
}
// The next element will be the ability key
if (it.hasNext()) {
final PCGElement element = it.next();
String abilityKey = EntityEncoder.decode(element.getText());
// Check for an ability that has been updated.
CategorisedKey categorisedKey = AbilityMigration.getNewAbilityKey(abilityCat, abilityKey, pcgenVersion, SettingsHandler.getGame().getName());
abilityCat = categorisedKey.getCategory();
abilityKey = categorisedKey.getKey();
AbilityCategory innateCategory = SettingsHandler.getGame().getAbilityCategory(abilityCat);
if (innateCategory == null) {
missingCat = abilityCat;
}
if (innateCategory == null || category == null) {
final String msg = LanguageBundle.getFormattedString(//$NON-NLS-1$
"Warnings.PCGenParser.AbilityCategoryNotFound", abilityKey, missingCat);
warnings.add(msg);
return;
}
ability = Globals.getContext().getReferenceContext().silentlyGetConstructedCDOMObject(Ability.class, innateCategory, abilityKey);
if (ability == null) {
warnings.add("Unable to Find Ability: " + abilityKey);
return;
}
}
List<String> associations = new ArrayList<>();
List<BonusObj> bonuses = new ArrayList<>();
while (it.hasNext()) {
final PCGElement element = it.next();
final String tag = element.getName();
if (tag.equals(IOConstants.TAG_APPLIEDTO)) {
associations.add(EntityEncoder.decode(element.getText()));
} else if (IOConstants.TAG_SAVE.equals(tag)) {
final String saveKey = EntityEncoder.decode(element.getText());
// TODO - This never gets written to the file
if (saveKey.startsWith(IOConstants.TAG_BONUS) && (saveKey.length() > 6)) {
final BonusObj aBonus = Bonus.newBonus(Globals.getContext(), saveKey.substring(6));
if (aBonus != null) {
bonuses.add(aBonus);
}
} else {
if (Logging.isDebugMode()) {
Logging.debugPrint("Ignoring SAVE:" + saveKey);
}
}
}
}
if (ability != null && category != null && nature != null) {
CNAbility cna = null;
boolean needError = true;
if (nature == Nature.NORMAL) {
// lines, save the feat now.
if (!featsPresent || category != AbilityCategory.FEAT) {
try {
cna = CNAbilityFactory.getCNAbility(category, nature, ability);
} catch (IllegalArgumentException e) {
Logging.log(Logging.INFO, "Unabe to parse ability line: " + e.getMessage());
}
} else {
needError = false;
}
} else if (nature == Nature.VIRTUAL) {
cna = CNAbilityFactory.getCNAbility(category, nature, ability);
}
if (cna == null) {
if (needError) {
warnings.add("Unable to build Ability: " + ability);
}
} else {
if (ability.getSafe(ObjectKey.MULTIPLE_ALLOWED)) {
for (String appliedToKey : associations) {
String[] assoc = appliedToKey.split(Constants.COMMA, -1);
for (String string : assoc) {
CNAbilitySelection cnas = new CNAbilitySelection(cna, string);
try {
if (nature == Nature.VIRTUAL) {
thePC.addSavedAbility(cnas, UserSelection.getInstance(), UserSelection.getInstance());
} else {
thePC.addAbility(cnas, UserSelection.getInstance(), UserSelection.getInstance());
}
} catch (IllegalArgumentException e) {
Logging.errorPrint("PCGVer2Parser.parseAbilityLine failed", e);
warnings.add(cna + " with selection: " + string + " is no longer valid.");
}
}
}
} else {
if (associations != null && !associations.isEmpty()) {
warnings.add(cna + " found with selections: " + associations + " but is MULT:NO in the data");
}
CNAbilitySelection cnas = new CNAbilitySelection(cna);
if (nature == Nature.VIRTUAL) {
thePC.addSavedAbility(cnas, UserSelection.getInstance(), UserSelection.getInstance());
} else {
thePC.addAbility(cnas, UserSelection.getInstance(), UserSelection.getInstance());
}
}
for (BonusObj b : bonuses) {
thePC.addSaveableBonus(b, cna.getAbility());
}
}
}
}
Aggregations