Search in sources :

Example 86 with Formula

use of pcgen.base.formula.Formula in project pcgen by PCGen.

the class EquipToken method unparse.

@Override
public String[] unparse(LoadContext context, CDOMObject obj) {
    Changes<PersistentTransitionChoice<?>> grantChanges = context.getObjectContext().getListChanges(obj, ListKey.ADD);
    Collection<PersistentTransitionChoice<?>> addedItems = grantChanges.getAdded();
    if (addedItems == null || addedItems.isEmpty()) {
        // Zero indicates no Token
        return null;
    }
    List<String> addStrings = new ArrayList<>();
    for (TransitionChoice<?> container : addedItems) {
        SelectableSet<?> cs = container.getChoices();
        if (EQUIPMENT_CLASS.equals(cs.getChoiceClass())) {
            Formula f = container.getCount();
            if (f == null) {
                context.addWriteMessage("Unable to find " + getFullName() + " Count");
                return null;
            }
            if (f.isStatic() && f.resolveStatic().doubleValue() <= 0) {
                context.addWriteMessage("Count in " + getFullName() + " must be > 0");
                return null;
            }
            StringBuilder sb = new StringBuilder();
            if (!FormulaFactory.ONE.equals(f)) {
                sb.append(f).append(Constants.PIPE);
            }
            sb.append(cs.getLSTformat());
            addStrings.add(sb.toString());
        // assoc.getAssociation(AssociationKey.CHOICE_MAXCOUNT);
        }
    }
    return addStrings.toArray(new String[addStrings.size()]);
}
Also used : Formula(pcgen.base.formula.Formula) ConcretePersistentTransitionChoice(pcgen.cdom.base.ConcretePersistentTransitionChoice) PersistentTransitionChoice(pcgen.cdom.base.PersistentTransitionChoice) ArrayList(java.util.ArrayList)

Example 87 with Formula

use of pcgen.base.formula.Formula in project pcgen by PCGen.

the class Bonus method newBonus.

/**
	 * Create a new Bonus
	 * @param context TODO
	 * @param bonusString
	 * @return BonusObj
	 * 
	 * TODO - This is doing all manner of string parsing.  It really belongs in
	 * the persistence layer.
	 */
public static BonusObj newBonus(LoadContext context, final String bonusString) {
    ParsingSeparator sep = new ParsingSeparator(bonusString, '|');
    sep.addGroupingPair('[', ']');
    sep.addGroupingPair('(', ')');
    if ((bonusString.indexOf(Constants.PIPE) == bonusString.lastIndexOf(Constants.PIPE)) && bonusString.indexOf('%') < 0) {
        Logging.errorPrint("Illegal bonus format: " + bonusString);
        return null;
    }
    String bonusName = sep.next();
    try {
        //Throw away old level value if present
        Integer.parseInt(bonusName);
        bonusName = sep.next().toUpperCase();
    } catch (NumberFormatException exc) {
        bonusName = bonusName.toUpperCase();
    }
    int equalOffset = -1;
    Class<? extends BonusObj> bEntry = TokenLibrary.getBonus(bonusName);
    String typeOfBonus = bonusName;
    if (bEntry == null) {
        equalOffset = bonusName.indexOf('=');
        if (equalOffset >= 0) {
            typeOfBonus = bonusName.substring(0, equalOffset + 1);
            bEntry = TokenLibrary.getBonus(typeOfBonus);
        }
        if (bEntry == null) {
            typeOfBonus = Bonus.BONUS_UNDEFINED;
            Logging.errorPrint("Unrecognized bonus: " + bonusString);
            return null;
        }
    }
    String bonusInfo = sep.next();
    String bValue = "0";
    if (sep.hasNext()) {
        bValue = sep.next();
    }
    if (bValue.startsWith("PRE") || bValue.startsWith("!PRE")) {
        Logging.errorPrint("Invalid BONUS has no value: " + bonusString);
        return null;
    }
    bValue = bValue.toUpperCase();
    BonusObj aBonus = null;
    try {
        aBonus = bEntry.newInstance();
    } catch (Exception exc) {
        Logging.errorPrint("Could not create bonusObj for:" + bonusString);
        return null;
    }
    aBonus.putOriginalString(bonusString.intern());
    aBonus.setBonusName(bonusName.intern());
    aBonus.setTypeOfBonus(typeOfBonus.intern());
    Formula val = aBonus.setValue(bValue.intern());
    if (!val.isValid()) {
        Logging.errorPrint("Could not create bonusObj for:" + bonusString + " since Formula " + bValue + " is not valid: " + val.toString());
        return null;
    }
    while (sep.hasNext()) {
        final String aString = sep.next().toUpperCase();
        if (PreParserFactory.isPreReqString(aString)) {
            try {
                final PreParserFactory factory = PreParserFactory.getInstance();
                aBonus.addPrerequisite(factory.parse(aString));
            } catch (PersistenceLayerException ple) {
                Logging.errorPrint(ple.getMessage(), ple);
                Logging.reportSource(Logging.ERROR, context);
                return null;
            }
        } else if (aString.startsWith("TYPE=") || aString.startsWith("TYPE.")) {
            String bonusType = aString.substring(5);
            int dotLoc = bonusType.indexOf('.');
            if (dotLoc != -1) {
                final String stackingFlag = bonusType.substring(dotLoc + 1);
                // built into the code.
                if (//$NON-NLS-1$
                stackingFlag.startsWith("REPLACE")) {
                    aBonus.setStackingFlag(StackType.REPLACE);
                } else if (//$NON-NLS-1$
                stackingFlag.startsWith("STACK")) {
                    aBonus.setStackingFlag(StackType.STACK);
                }
            }
            final boolean result = aBonus.addType(bonusType.intern());
            if (!result) {
                Logging.log(Logging.LST_ERROR, new StringBuilder().append("Could not add type ").append(aString.substring(5)).append(" to bonusType ").append(typeOfBonus).append(" in Bonus.newBonus").toString());
                Logging.reportSource(Logging.LST_ERROR, context);
                return null;
            }
        }
    }
    if (equalOffset >= 0) {
        aBonus.setVariable(bonusName.substring(equalOffset + 1).intern());
    }
    if (!aBonus.requiresRealCaseTarget()) {
        bonusInfo = bonusInfo.toUpperCase();
    }
    StringTokenizer aTok = new StringTokenizer(bonusInfo, ",");
    if (!aTok.hasMoreTokens()) {
        Logging.log(Logging.LST_ERROR, new StringBuilder().append("Could not parse empty target ").append(" from BONUS:").append(bonusString).toString());
        Logging.reportSource(Logging.LST_ERROR, context);
        return null;
    }
    LstUtils.deprecationCheck(aBonus, bonusName, bonusString);
    while (aTok.hasMoreTokens()) {
        final String token = aTok.nextToken();
        final boolean result = aBonus.parseToken(context, token);
        if (!result) {
            Logging.log(Logging.LST_ERROR, new StringBuilder().append("Could not parse token ").append(token).append(" from BONUS:").append(bonusString).toString());
            Logging.reportSource(Logging.LST_ERROR, context);
            return null;
        }
    }
    return aBonus;
}
Also used : PreParserFactory(pcgen.persistence.lst.prereq.PreParserFactory) PersistenceLayerException(pcgen.persistence.PersistenceLayerException) PersistenceLayerException(pcgen.persistence.PersistenceLayerException) Formula(pcgen.base.formula.Formula) StringTokenizer(java.util.StringTokenizer) ParsingSeparator(pcgen.base.text.ParsingSeparator)

Example 88 with Formula

use of pcgen.base.formula.Formula in project pcgen by PCGen.

the class DomainApplication method applyDomain.

/**
	 * 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);
                }
            }
        }
    }
}
Also used : PCClass(pcgen.core.PCClass) Spell(pcgen.core.spell.Spell) CharacterSpell(pcgen.core.character.CharacterSpell) DomainSpellList(pcgen.cdom.list.DomainSpellList) Formula(pcgen.base.formula.Formula) CharacterSpell(pcgen.core.character.CharacterSpell) ClassSource(pcgen.cdom.helper.ClassSource) CDOMReference(pcgen.cdom.base.CDOMReference) AssociatedPrereqObject(pcgen.cdom.base.AssociatedPrereqObject)

Example 89 with Formula

use of pcgen.base.formula.Formula in project pcgen by PCGen.

the class SpellSupportForPCClass method updateSpellCache.

public boolean updateSpellCache(boolean force) {
    if (force || !spellCacheValid) {
        SpellProgressionCache cache = new SpellProgressionCache();
        for (PCClassLevel cl : source.getOriginalClassLevelCollection()) {
            Integer lvl = cl.get(IntegerKey.LEVEL);
            List<Formula> cast = cl.getListFor(ListKey.CAST);
            if (cast != null) {
                cache.setCast(lvl, cast);
            }
            List<Formula> known = cl.getListFor(ListKey.KNOWN);
            if (known != null) {
                cache.setKnown(lvl, known);
            }
            List<Formula> spec = cl.getListFor(ListKey.SPECIALTYKNOWN);
            if (spec != null) {
                cache.setSpecialtyKnown(lvl, spec);
            }
        }
        if (!cache.isEmpty()) {
            spellCache = cache;
        }
        spellCacheValid = true;
    }
    return spellCache != null;
}
Also used : Formula(pcgen.base.formula.Formula) PCClassLevel(pcgen.cdom.inst.PCClassLevel)

Example 90 with Formula

use of pcgen.base.formula.Formula in project pcgen by PCGen.

the class SpellSupportForPCClass method getKnownForLevel.

public int getKnownForLevel(int spellLevel, PlayerCharacter aPC) {
    int total = 0;
    int stat = 0;
    final String classKeyName = "CLASS." + source.getKeyName();
    final String levelSpellLevel = ";LEVEL." + spellLevel;
    final String allSpellLevel = ";LEVEL.All";
    int pcLevel = aPC.getLevel(source);
    pcLevel += (int) aPC.getTotalBonusTo("PCLEVEL", source.getKeyName());
    pcLevel += (int) aPC.getTotalBonusTo("PCLEVEL", "TYPE." + source.getSpellType());
    /*
		 * CONSIDER Why is known testing getNumFromCastList??? - thpr 11/8/06
		 */
    if (updateSpellCache(false) && spellCache.hasCastProgression() && (getNumFromCastList(pcLevel, spellLevel, aPC) < 0)) {
        // feats
        return (int) aPC.getTotalBonusTo("SPELLKNOWN", classKeyName + levelSpellLevel);
    }
    total += (int) aPC.getTotalBonusTo("SPELLKNOWN", classKeyName + levelSpellLevel);
    total += (int) aPC.getTotalBonusTo("SPELLKNOWN", "TYPE." + source.getSpellType() + levelSpellLevel);
    total += (int) aPC.getTotalBonusTo("SPELLKNOWN", "CLASS.Any" + levelSpellLevel);
    total += (int) aPC.getTotalBonusTo("SPELLKNOWN", classKeyName + allSpellLevel);
    total += (int) aPC.getTotalBonusTo("SPELLKNOWN", "TYPE." + source.getSpellType() + allSpellLevel);
    total += (int) aPC.getTotalBonusTo("SPELLKNOWN", "CLASS.Any" + allSpellLevel);
    PCStat aStat = source.baseSpellStat();
    String statString = Constants.NONE;
    if (aStat != null) {
        stat = aPC.getTotalStatFor(aStat);
        statString = aStat.getKeyName();
    }
    final int bonusStat = (int) aPC.getTotalBonusTo("STAT", "KNOWN." + statString) + (int) aPC.getTotalBonusTo("STAT", "BASESPELLKNOWNSTAT") + (int) aPC.getTotalBonusTo("STAT", "BASESPELLKNOWNSTAT;CLASS=" + source.getKeyName());
    if (!source.getSafe(ObjectKey.USE_SPELL_SPELL_STAT) && !source.getSafe(ObjectKey.CASTER_WITHOUT_SPELL_STAT)) {
        final int maxSpellLevel = aPC.getVariableValue("MAXLEVELSTAT=" + statString, "").intValue();
        if ((maxSpellLevel + bonusStat) < spellLevel) {
            return total;
        }
    }
    stat += bonusStat;
    int mult = (int) aPC.getTotalBonusTo("SPELLKNOWNMULT", classKeyName + levelSpellLevel);
    mult += (int) aPC.getTotalBonusTo("SPELLKNOWNMULT", "TYPE." + source.getSpellType() + levelSpellLevel);
    if (mult < 1) {
        mult = 1;
    }
    if (!updateSpellCache(false)) {
        return total;
    }
    if (spellCache.hasKnownProgression()) {
        List<Formula> knownList = spellCache.getKnownForLevel(pcLevel);
        if (spellLevel >= 0 && knownList != null && spellLevel < knownList.size()) {
            total += mult * knownList.get(spellLevel).resolve(aPC, "").intValue();
            // add Stat based bonus
            BonusSpellInfo bsi = Globals.getContext().getReferenceContext().silentlyGetConstructedCDOMObject(BonusSpellInfo.class, String.valueOf(spellLevel));
            if (Globals.checkRule(RuleConstants.BONUSSPELLKNOWN) && (bsi != null) && bsi.isValid()) {
                int base = bsi.getStatScore();
                if (stat >= base) {
                    int range = bsi.getStatRange();
                    total += Math.max(0, (stat - base + range) / range);
                }
            }
        }
    }
    // or a psi specialty.
    if (total > 0 && spellLevel > 0) {
        // make sure any slots due from specialties
        total += source.getSafe(IntegerKey.KNOWN_SPELLS_FROM_SPECIALTY);
        // (including domains) are added
        Integer assoc = aPC.getDomainSpellCount(source);
        if (assoc != null) {
            total += assoc;
        }
    }
    // Add in any from SPELLKNOWN
    total += aPC.getKnownSpellCountForLevel(source.get(ObjectKey.CLASS_SPELLLIST), spellLevel);
    return total;
}
Also used : Formula(pcgen.base.formula.Formula) BonusSpellInfo(pcgen.cdom.content.BonusSpellInfo)

Aggregations

Formula (pcgen.base.formula.Formula)106 ArrayList (java.util.ArrayList)30 ParsingSeparator (pcgen.base.text.ParsingSeparator)26 ConcretePersistentTransitionChoice (pcgen.cdom.base.ConcretePersistentTransitionChoice)18 ParseResult (pcgen.rules.persistence.token.ParseResult)18 CDOMReference (pcgen.cdom.base.CDOMReference)16 StringTokenizer (java.util.StringTokenizer)15 ChoiceSet (pcgen.cdom.base.ChoiceSet)11 Ungranted (pcgen.cdom.base.Ungranted)10 CDOMObject (pcgen.cdom.base.CDOMObject)9 PersistentTransitionChoice (pcgen.cdom.base.PersistentTransitionChoice)9 ReferenceChoiceSet (pcgen.cdom.choiceset.ReferenceChoiceSet)8 PCClass (pcgen.core.PCClass)7 Prerequisite (pcgen.core.prereq.Prerequisite)7 Map (java.util.Map)6 AssociatedPrereqObject (pcgen.cdom.base.AssociatedPrereqObject)6 PCTemplate (pcgen.core.PCTemplate)6 Race (pcgen.core.Race)6 Spell (pcgen.core.spell.Spell)6 HashMap (java.util.HashMap)5