/** * Sets the locked flag on a PC * * @param pc */ public static void applyDomain(PlayerCharacter pc, Domain d) { ClassSource source = pc.getDomainSource(d); PCClass aClass = pc.getClassKeyed(source.getPcclass().getKeyName()); if (aClass != null) { int maxLevel; for (maxLevel = 0; maxLevel < 10; maxLevel++) { if (pc.getSpellSupport(aClass).getCastForLevel(maxLevel, pc) == 0) { break; } } if (maxLevel > 0) { addSpellsToClassForLevels(pc, d, aClass, 0, maxLevel - 1); } if ((maxLevel > 1) && (aClass.getSafe(IntegerKey.KNOWN_SPELLS_FROM_SPECIALTY) == 0)) { DomainSpellList domainSpellList = d.get(ObjectKey.DOMAIN_SPELLLIST); final List<Spell> aList = pc.getAllSpellsInLists(Collections.singletonList(domainSpellList)); for (Spell gcs : aList) { if (SpellLevel.getFirstLvlForKey(gcs, domainSpellList, pc) < maxLevel) { pc.setDomainSpellCount(aClass, 1); break; } } } } Collection<CDOMReference<Spell>> mods = d.getSafeListMods(Spell.SPELLS); for (CDOMReference<Spell> ref : mods) { Collection<Spell> spells = ref.getContainedObjects(); Collection<AssociatedPrereqObject> assoc = d.getListAssociations(Spell.SPELLS, ref); for (AssociatedPrereqObject apo : assoc) { if (!PrereqHandler.passesAll(apo.getPrerequisiteList(), pc, d)) { continue; } for (Spell s : spells) { String book = apo.getAssociation(AssociationKey.SPELLBOOK); List<CharacterSpell> aList = pc.getCharacterSpells(aClass, s, book, -1); if (aList.isEmpty()) { Formula times = apo.getAssociation(AssociationKey.TIMES_PER_UNIT); CharacterSpell cs = new CharacterSpell(d, s); int resolvedTimes = times.resolve(pc, d.getQualifiedKey()).intValue(); cs.addInfo(1, resolvedTimes, book); pc.addCharacterSpell(aClass, cs); } } } } }
@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<String>(); TripleKeyMapToList< Nature, CDOMSingleRef<AbilityCategory>, List<Prerequisite>, CDOMReference<Ability>> m = new TripleKeyMapToList< Nature, CDOMSingleRef<AbilityCategory>, List<Prerequisite>, CDOMReference<Ability>>(); TripleKeyMapToList< Nature, CDOMSingleRef<AbilityCategory>, List<Prerequisite>, CDOMReference<Ability>> clear = new TripleKeyMapToList< Nature, CDOMSingleRef<AbilityCategory>, List<Prerequisite>, CDOMReference<Ability>>(); 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()]); }
@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<PrereqObject>(); 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<String>(); 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; }
@Override protected ParseResult parseTokenWithSeparator(LoadContext context, CDOMObject obj, String value) { AbilityCategory category = AbilityCategory.FEAT; Nature nature = Nature.AUTOMATIC; StringTokenizer tok = new StringTokenizer(value, Constants.PIPE); String token = tok.nextToken(); if (looksLikeAPrerequisite(token)) { return new ParseResult.Fail( "Cannot have only PRExxx subtoken in " + getFullName() + ": " + value, context); } ArrayList<PrereqObject> edgeList = new ArrayList<PrereqObject>(); CDOMReference<AbilityList> abilList = AbilityList.getAbilityListReference(category, nature); boolean first = true; boolean allowPre = true; ReferenceManufacturer<Ability> rm = context.getReferenceContext().getManufacturer(ABILITY_CLASS, AbilityCategory.FEAT); while (true) { if (Constants.LST_DOT_CLEAR.equals(token)) { if (!first) { return new ParseResult.Fail( " Non-sensical " + getFullName() + ": .CLEAR was not the first list item: " + value, context); } context.getListContext().removeAllFromList(getFullName(), obj, abilList); allowPre = false; } 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; } context.getListContext().removeFromList(getFullName(), obj, abilList, ref); allowPre = false; } else if (Constants.LST_PERCENT_LIST.equals(token)) { ConditionalSelectionActor<AbilitySelection> cca = new ConditionalSelectionActor<AbilitySelection>( new AbilitySelector(SOURCE, AbilityCategory.FEAT, Nature.AUTOMATIC)); edgeList.add(cca); context.getObjectContext().addToList(obj, ListKey.NEW_CHOOSE_ACTOR, cca); allowPre = false; } 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<String>(); 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(SOURCE, category, ref, nature); context.getObjectContext().addToList(obj, ListKey.NEW_CHOOSE_ACTOR, ats); edgeList.add(ats); loadList = false; } } } if (loadList) { AssociatedPrereqObject assoc = context.getListContext().addToList(getFullName(), obj, abilList, ability); assoc.setAssociation(AssociationKey.NATURE, nature); assoc.setAssociation(AssociationKey.CATEGORY, category); 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 (!allowPre) { 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 " + getFullName() + ":?)", context); } for (PrereqObject edge : edgeList) { edge.addPrerequisite(prereq); } if (!tok.hasMoreTokens()) { break; } token = tok.nextToken(); } return ParseResult.SUCCESS; }
@Override public String[] unparse(LoadContext context, CDOMObject obj) { Set<String> returnSet = new TreeSet<String>(); List<String> returnList = new ArrayList<String>(); MapToList<List<Prerequisite>, CDOMReference<Ability>> m = new HashMapToList<List<Prerequisite>, CDOMReference<Ability>>(); AbilityCategory category = AbilityCategory.FEAT; Nature nature = Nature.AUTOMATIC; CDOMReference<AbilityList> abilList = AbilityList.getAbilityListReference(category, nature); AssociatedChanges<CDOMReference<Ability>> changes = context.getListContext().getChangesInList(getFullName(), obj, abilList); Collection<CDOMReference<Ability>> 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; } returnList.add(Constants.LST_DOT_CLEAR); } else if (removedItems != null && !removedItems.isEmpty()) { returnList.add( Constants.LST_DOT_CLEAR_DOT + ReferenceUtilities.joinLstFormat(removedItems, "|.CLEAR.", true)); } 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(SOURCE)) { try { returnList.add(csa.getLstFormat()); } catch (PersistenceLayerException e) { context.addWriteMessage(getTokenName() + " encountered error: " + e.getMessage()); return null; } } } } MapToList<CDOMReference<Ability>, AssociatedPrereqObject> mtl = changes.getAddedAssociations(); if (mtl != null) { for (CDOMReference<Ability> ab : mtl.getKeySet()) { for (AssociatedPrereqObject assoc : mtl.getListFor(ab)) { m.addToListFor(assoc.getPrerequisiteList(), ab); } } } for (List<Prerequisite> prereqs : m.getKeySet()) { StringBuilder sb = new StringBuilder(); sb.append(ReferenceUtilities.joinLstFormat(m.getListFor(prereqs), Constants.PIPE)); if (prereqs != null && !prereqs.isEmpty()) { sb.append(Constants.PIPE); sb.append(getPrerequisiteString(context, prereqs)); } returnSet.add(sb.toString()); } returnList.addAll(returnSet); return returnList.toArray(new String[returnList.size()]); }