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()]);
}
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;
}
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);
}
}
}
}
}
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;
}
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;
}
Aggregations