use of pcgen.core.Language in project pcgen by PCGen.
the class LangToken method parseNonEmptyToken.
@Override
protected ParseResult parseNonEmptyToken(LoadContext context, CDOMObject obj, String value) {
String lang = value;
ParseResult pr = checkSeparatorsAndNonEmpty('|', lang);
if (!pr.passed()) {
return pr;
}
boolean foundAny = false;
boolean foundOther = false;
StringTokenizer tok = new StringTokenizer(lang, Constants.PIPE);
boolean isPre = false;
// Do not initialize, null is significant!
Prerequisite prereq = null;
while (tok.hasMoreTokens()) {
String token = tok.nextToken();
if (PreParserFactory.isPreReqString(token)) {
if (isPre) {
String errorText = "Invalid " + getTokenName() + ": " + value + " PRExxx must be at the END of the Token";
Logging.errorPrint(errorText);
return new ParseResult.Fail(errorText, context);
}
prereq = getPrerequisite(token);
if (prereq == null) {
return new ParseResult.Fail("Error generating Prerequisite " + prereq + " in " + getFullName(), context);
}
int preStart = value.indexOf(token) - 1;
lang = value.substring(0, preStart);
isPre = true;
}
}
boolean firstToken = true;
tok = new StringTokenizer(lang, Constants.PIPE);
while (tok.hasMoreTokens()) {
String token = tok.nextToken();
if (Constants.LST_DOT_CLEAR.equals(token)) {
if (!firstToken) {
return new ParseResult.Fail("Non-sensical situation was " + "encountered while parsing " + getTokenName() + ": When used, .CLEAR must be the first argument", context);
}
context.getObjectContext().removeList(obj, ListKey.AUTO_LANGUAGE);
} else if (Constants.LST_PERCENT_LIST.equals(token)) {
ChooseSelectionActor<Language> cra;
if (prereq == null) {
cra = this;
} else {
ConditionalSelectionActor<Language> cca = new ConditionalSelectionActor<>(this);
cca.addPrerequisite(prereq);
cra = cca;
}
foundOther = true;
context.getObjectContext().addToList(obj, ListKey.NEW_CHOOSE_ACTOR, cra);
} else if (Constants.LST_ALL.equals(token)) {
foundAny = true;
context.getObjectContext().addToList(obj, ListKey.AUTO_LANGUAGE, new QualifiedObject<>(context.getReferenceContext().getCDOMAllReference(LANGUAGE_CLASS), prereq));
} else {
foundOther = true;
CDOMReference<Language> ref = TokenUtilities.getTypeOrPrimitive(context, LANGUAGE_CLASS, token);
if (ref == null) {
return new ParseResult.Fail(" Error was encountered while parsing " + getTokenName(), context);
}
context.getObjectContext().addToList(obj, ListKey.AUTO_LANGUAGE, new QualifiedObject<>(ref, prereq));
}
firstToken = false;
}
if (foundAny && foundOther) {
return new ParseResult.Fail("Non-sensical " + getFullName() + ": Contains ANY and a specific reference: " + value, context);
}
return ParseResult.SUCCESS;
}
use of pcgen.core.Language in project pcgen by PCGen.
the class LanguageToken method parseNonEmptyToken.
@Override
protected ParseResult parseNonEmptyToken(LoadContext context, CDOMObject obj, String value) {
ParsingSeparator sep = new ParsingSeparator(value, '|');
sep.addGroupingPair('[', ']');
sep.addGroupingPair('(', ')');
String activeValue = sep.next();
Formula count;
if (!sep.hasNext()) {
count = FormulaFactory.ONE;
} else {
count = FormulaFactory.getFormulaFor(activeValue);
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);
}
activeValue = sep.next();
}
if (sep.hasNext()) {
return new ParseResult.Fail(getFullName() + " had too many pipe separated items: " + value, context);
}
ParseResult pr = checkSeparatorsAndNonEmpty(',', activeValue);
if (!pr.passed()) {
return pr;
}
List<CDOMReference<Language>> refs = new ArrayList<>();
StringTokenizer tok = new StringTokenizer(activeValue, Constants.COMMA);
while (tok.hasMoreTokens()) {
String tokText = tok.nextToken();
CDOMReference<Language> lang = TokenUtilities.getReference(context, LANGUAGE_CLASS, tokText);
if (lang == null) {
return new ParseResult.Fail(" Error was encountered while parsing " + getFullName() + ": " + value + " had an invalid reference: " + tokText, context);
}
refs.add(lang);
}
ReferenceChoiceSet<Language> rcs = new ReferenceChoiceSet<>(refs);
if (!rcs.getGroupingState().isValid()) {
return new ParseResult.Fail("Non-sensical " + getFullName() + ": Contains ANY and a specific reference: " + value, context);
}
ChoiceSet<Language> cs = new ChoiceSet<>(getTokenName(), rcs);
cs.setTitle("Language Choice");
PersistentTransitionChoice<Language> tc = new ConcretePersistentTransitionChoice<>(cs, count);
context.getObjectContext().addToList(obj, ListKey.ADD, tc);
tc.setChoiceActor(this);
return ParseResult.SUCCESS;
}
use of pcgen.core.Language in project pcgen by PCGen.
the class PCGVer2Parser method resolveLanguages.
private void resolveLanguages() {
CNAbility langbonus = thePC.getBonusLanguageAbility();
int currentBonusLang = thePC.getDetailedAssociationCount(langbonus);
boolean foundLang = currentBonusLang > 0;
Set<Language> foundLanguages = new HashSet<>(thePC.getLanguageSet());
//Captures Auto (AUTO:LANG) and Persistent choices (ADD ex ability and CHOOSE)
cachedLanguages.removeAll(foundLanguages);
HashMapToList<Language, Object> langSources = new HashMapToList<>();
Map<Object, Integer> actorLimit = new IdentityHashMap<>();
Map<PersistentTransitionChoice, CDOMObject> ptcSources = new IdentityHashMap<>();
List<? extends CDOMObject> abilities = thePC.getCDOMObjectList();
for (CDOMObject a : abilities) {
List<PersistentTransitionChoice<?>> addList = a.getListFor(ListKey.ADD);
if (addList != null) {
for (PersistentTransitionChoice<?> ptc : addList) {
SelectableSet<?> ss = ptc.getChoices();
if (ss.getName().equals("LANGUAGE") && LANGUAGE_CLASS.equals(ss.getChoiceClass())) {
Collection<Language> selected = (Collection<Language>) ss.getSet(thePC);
for (Language l : selected) {
if (cachedLanguages.contains(l)) {
String source = SourceFormat.getFormattedString(a, Globals.getSourceDisplay(), true);
int choiceCount = ptc.getCount().resolve(thePC, source).intValue();
if (choiceCount > 0) {
langSources.addToListFor(l, ptc);
ptcSources.put(ptc, a);
actorLimit.put(ptc, choiceCount);
}
}
}
}
}
}
}
if (!foundLang) {
Set<Language> bonusAllowed = thePC.getLanguageBonusSelectionList();
int count = thePC.getBonusLanguageCount();
int choiceCount = count - currentBonusLang;
if (choiceCount > 0) {
for (Language l : bonusAllowed) {
if (cachedLanguages.contains(l)) {
langSources.addToListFor(l, langbonus);
actorLimit.put(langbonus, choiceCount);
}
}
}
}
//Try to match them up as best as possible (this matches things with only one possible location...)
boolean acted = !cachedLanguages.isEmpty();
while (acted) {
acted = false;
for (Language l : langSources.getKeySet()) {
List<Object> actors = langSources.getListFor(l);
if ((actors != null) && (actors.size() == 1)) {
Object actor = actors.get(0);
acted = true;
processRemoval(langbonus, langSources, actorLimit, ptcSources, l, actor);
}
}
if (!acted && !langSources.isEmpty() && !actorLimit.isEmpty()) {
//pick one
Language l = langSources.getKeySet().iterator().next();
Object source = langSources.getListFor(l).get(0);
processRemoval(langbonus, langSources, actorLimit, ptcSources, l, source);
acted = true;
}
}
for (Language l : cachedLanguages) {
warnings.add("Unable to find source: " + "Character no longer speaks language: " + l.getDisplayName());
}
}
use of pcgen.core.Language in project pcgen by PCGen.
the class KitLangBonus method testApply.
/**
* Prepare the languages to be added and test their application.
*
* @param aPC The character to be processed.
* @param aKit The kit being processed
* @param warnings List of warnigns.
*
* @return true, if the languages could be added
*/
@Override
public boolean testApply(Kit aKit, PlayerCharacter aPC, List<String> warnings) {
theLanguages = new ArrayList<>();
CNAbility cna = aPC.getBonusLanguageAbility();
List<String> reservedList = new ArrayList<>();
/*
* While this direct use of the controller seems strange, the use of
* conditionallyApply in the controller is reasonable (there is no need
* to actually try to apply the langbonus ability in this case)
*/
ChoiceManagerList<Language> controller = ChooserUtilities.getConfiguredController(cna, aPC, AbilityCategory.LANGBONUS, reservedList);
if (controller == null) {
return false;
}
int allowedCount = aPC.getAvailableAbilityPool(AbilityCategory.LANGBONUS).intValue();
int remaining = allowedCount;
for (CDOMSingleRef<Language> ref : langList) {
Language lang = ref.get();
if (remaining > 0 && controller.conditionallyApply(aPC, lang)) {
theLanguages.add(lang);
remaining--;
} else {
warnings.add("LANGUAGE: Could not add bonus language \"" + lang.getKeyName() + "\"");
}
}
if (langList.size() > allowedCount) {
warnings.add("LANGUAGE: Too many bonus languages specified. " + (langList.size() - allowedCount) + " had to be ignored.");
}
if (!theLanguages.isEmpty()) {
return true;
}
return false;
}
use of pcgen.core.Language in project pcgen by PCGen.
the class LanguageChooserFacadeImpl method buildBonusLangList.
/**
* Build up the language lists for a choice of racial bonus languages.
*/
private void buildBonusLangList() {
CNAbility cna = theCharacter.getBonusLanguageAbility();
Ability a = cna.getAbility();
List<Language> availLangs = new ArrayList<>();
ChooseInformation<Language> chooseInfo = (ChooseInformation<Language>) a.get(ObjectKey.CHOOSE_INFO);
availLangs.addAll(chooseInfo.getSet(theCharacter));
List<? extends Language> selLangs = chooseInfo.getChoiceActor().getCurrentlySelected(cna, theCharacter);
if (selLangs == null) {
selLangs = Collections.emptyList();
}
availLangs.removeAll(charDisplay.getLanguageSet());
refreshLangListContents(availLangs, availableList);
refreshLangListContents(selLangs, selectedList);
refreshLangListContents(selLangs, originalSelectedList);
boolean allowBonusLangAfterFirst = Globals.checkRule(RuleConstants.INTBONUSLANG);
boolean atFirstLvl = theCharacter.getTotalLevels() <= 1;
if (allowBonusLangAfterFirst || atFirstLvl) {
int bonusLangMax = theCharacter.getBonusLanguageCount();
numSelectionsRemain.set(bonusLangMax - selLangs.size());
} else {
numSelectionsRemain.set(0);
}
}
Aggregations