@Override public void applyChoice( CDOMObject owner, CategorizedAbilitySelection choice, PlayerCharacter pc) { double cost = choice.getAbility().getSafe(ObjectKey.SELECTION_COST).doubleValue(); if (cost > 0.0001) { pc.adjustFeats(cost); } AbilityUtilities.modAbility( pc, choice.getAbility(), choice.getSelection(), AbilityCategory.FEAT); pc.addAssoc(owner, AssociationListKey.TEMPLATE_FEAT, choice); }
private AbilityRefChoiceSet build(String... names) { List<CDOMReference<Ability>> list = new ArrayList<CDOMReference<Ability>>(); for (String name : names) { Ability ab = construct(primaryContext, name); CDOMDirectSingleRef<Ability> ar = CDOMDirectSingleRef.getRef(ab); if (name.indexOf('(') != -1) { List<String> choices = new ArrayList<String>(); AbilityUtilities.getUndecoratedName(name, choices); assertEquals("Can't proceed if not true", 1, choices.size()); ar.setChoice(choices.get(0)); } list.add(ar); } AbilityRefChoiceSet rcs = new AbilityRefChoiceSet(AbilityCategory.FEAT, list, Nature.NORMAL); return rcs; }
@Override public void applyChoice( CDOMObject owner, CategorizedAbilitySelection choice, PlayerCharacter pc) { if (!pc.isImporting()) { pc.getSpellList(); } // See if our choice is not auto or virtual Ability anAbility = pc.getMatchingAbility(AbilityCategory.FEAT, choice.getAbility(), Nature.NORMAL); if (anAbility != null) { // how many sub-choices to make double abilityCount = (pc.getSelectCorrectedAssociationCount(anAbility) * anAbility.getSafe(ObjectKey.SELECTION_COST).doubleValue()); boolean result = false; // adjust the associated List if (anAbility.getSafe(ObjectKey.MULTIPLE_ALLOWED)) { pc.removeAssociation(anAbility, choice.getSelection()); result = pc.hasAssociations(anAbility); } boolean removed = false; // if no sub choices made (i.e. all of them removed in Chooser box), // then remove the Feat if (!result) { removed = pc.removeRealAbility(AbilityCategory.FEAT, anAbility); CDOMObjectUtilities.removeAdds(anAbility, pc); CDOMObjectUtilities.restoreRemovals(anAbility, pc); } AbilityUtilities.adjustPool(anAbility, pc, false, abilityCount, removed); pc.adjustMoveRates(); } double cost = choice.getAbility().getSafe(ObjectKey.SELECTION_COST).doubleValue(); pc.adjustAbilities(AbilityCategory.FEAT, BigDecimal.valueOf(-cost)); }
@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; }