/** * Adds available Languages to this facet when a CDOMObject added to a Player Character makes * Languages available to the Player Character. * * <p>Triggered when one of the Facets to which StartingLanguageFacet listens fires a * DataFacetChangeEvent to indicate a CDOMObject was added to a Player Character. * * @param dfce The DataFacetChangeEvent containing the information about the change * @see pcgen.cdom.facet.DataFacetChangeListener#dataAdded(pcgen.cdom.facet.DataFacetChangeEvent) */ @Override public void dataAdded(DataFacetChangeEvent<CDOMObject> dfce) { CDOMObject cdo = dfce.getCDOMObject(); Collection<CDOMReference<Language>> list = cdo.getListMods(Language.STARTING_LIST); if (list != null) { CharID id = dfce.getCharID(); for (CDOMReference<Language> ref : list) { addAll(id, ref.getContainedObjects(), cdo); } } }
/** * 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); } } } } }
/** * Adds the SkillCost objects granted by CDOMObjects added to the Player Character to this * GlobalSkillCostFacet. * * <p>Triggered when one of the Facets to which GlobalSkillCostFacet listens fires a * DataFacetChangeEvent to indicate a CDOMObject was added to a Player Character. * * @param dfce The DataFacetChangeEvent containing the information about the change * @see * pcgen.cdom.facet.event.DataFacetChangeListener#dataAdded(pcgen.cdom.facet.event.DataFacetChangeEvent) */ @Override public void dataAdded(DataFacetChangeEvent<CharID, CDOMObject> dfce) { CDOMObject cdo = dfce.getCDOMObject(); CharID id = dfce.getCharID(); for (CDOMReference<Skill> ref : cdo.getSafeListFor(ListKey.CSKILL)) { for (Skill sk : ref.getContainedObjects()) { add(id, SkillCost.CLASS, sk, cdo); } } for (CDOMReference<Skill> ref : cdo.getSafeListFor(ListKey.CCSKILL)) { for (Skill sk : ref.getContainedObjects()) { add(id, SkillCost.CROSS_CLASS, sk, cdo); } } }
@Override public String[] unparse(LoadContext context, CDOMObject obj) { Changes<ChangeProf> changes = context.getObjectContext().getListChanges(obj, ListKey.CHANGEPROF); Collection<ChangeProf> added = changes.getAdded(); if (added == null || added.isEmpty()) { // Zero indicates no Token return null; } HashMapToList<CDOMGroupRef<WeaponProf>, CDOMReference<WeaponProf>> m = new HashMapToList<CDOMGroupRef<WeaponProf>, CDOMReference<WeaponProf>>(); for (ChangeProf cp : added) { CDOMReference<WeaponProf> source = cp.getSource(); CDOMGroupRef<WeaponProf> result = cp.getResult(); m.addToListFor(result, source); } SortedSet<CDOMReference<WeaponProf>> set = new TreeSet<CDOMReference<WeaponProf>>(ReferenceUtilities.REFERENCE_SORTER); Set<String> returnSet = new TreeSet<String>(); for (CDOMGroupRef<WeaponProf> result : m.getKeySet()) { StringBuilder sb = new StringBuilder(); boolean needComma = false; set.clear(); set.addAll(m.getListFor(result)); for (CDOMReference<WeaponProf> source : set) { if (needComma) { sb.append(Constants.COMMA); } needComma = true; String sourceLst = source.getLSTformat(false); if (sourceLst.startsWith(Constants.LST_TYPE_EQUAL)) { sb.append(Constants.LST_TYPE_DOT); sb.append(sourceLst.substring(5)); } else { sb.append(sourceLst); } } sb.append(Constants.EQUALS).append(result.getLSTformat(false).substring(5)); returnSet.add(sb.toString()); } return new String[] {StringUtil.join(returnSet, Constants.PIPE)}; }
private List<Skill> getSkillChoices(PlayerCharacter aPC) { final List<Skill> skillsOfType = new ArrayList<Skill>(); for (CDOMReference<Skill> ref : skillList) { skillsOfType.addAll(ref.getContainedObjects()); } if (skillsOfType.size() == 0) { return null; } else if (skillsOfType.size() == 1) { return skillsOfType; } List<Skill> skillChoices = new ArrayList<Skill>(); skillChoices = Globals.getChoiceFromList("Select skill", skillsOfType, skillChoices, getSafeCount(), aPC); return skillChoices; }
@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; }