/**
* pcgen.core.term.EvaluatorFactoryPCVar.java
* Copyright 2008 Andrew Wilson
* <nuance@users.sourceforge.net>.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Created 03 August 2008
*
* Current Ver: $Revision:$
*/
package pcgen.core.term;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import pcgen.cdom.base.Constants;
import pcgen.core.AbilityCategory;
import pcgen.util.Logging;
import pcgen.util.TermUtilities;
/**
* {@code EvaluatorFactoryPCVar}
*
* This individual enumerations in this class are each responsible for making
* and returning an object that implements the TermEvaluator interface.
* Each enumeration has a regular expression that matches one of the
* "hardcoded" internal variables that every PC has a value for. They also
* have an array of string keys that enumerate every string that the regular
* expression can match (this is not as bad as it sounds since each can only
* match at most eight strings). The array of string is used to populate a
* {@code Map<String, Enum>}
*/
public enum TermEvaluatorBuilderPCVar implements TermEvaluatorBuilder
{
COMPLETE_PC_ACCHECK
("AC{1,2}HECK",
new String[] { "ACCHECK" , "ACHECK"},
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCACcheckTermEvaluator(expressionString);
}
},
COMPLETE_PC_ARMORACCHECK
("ARMORAC{1,2}HECK",
new String[] { "ARMORACCHECK", "ARMORACHECK" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCArmourACcheckTermEvaluator(expressionString);
}
},
COMPLETE_PC_BAB
("BAB",
new String[] { "BAB" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCBABTermEvaluator(expressionString);
}
},
COMPLETE_PC_BASECR
("BASECR",
new String[] { "BASECR" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCBaseCRTermEvaluator(expressionString);
}
},
COMPLETE_PC_BASEHD
("BASEHD",
new String[] { "BASEHD" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCBaseHDTermEvaluator(expressionString);
}
},
COMPLETE_PC_BASESPELLSTAT
("BASESPELLSTAT",
new String[] { "BASESPELLSTAT" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
String source = (src.startsWith("CLASS:")) ? src.substring(6) : "";
return new PCBaseSpellStatTermEvaluator(expressionString, source);
}
},
COMPLETE_PC_CASTERLEVEL
("(?:CASTERLEVEL\\.TOTAL|CASTERLEVEL)",
new String[] { "CASTERLEVEL", "CASTERLEVEL.TOTAL" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
if ("CASTERLEVEL".equals(matchedSection))
{
if (src.startsWith("RACE:"))
{
return new PCCasterLevelRaceTermEvaluator(
expressionString,
src.substring(5));
}
else if (src.startsWith("CLASS:"))
{
return new PCCasterLevelClassTermEvaluator(
expressionString,
src.substring(6));
}
else
{
return new PCCasterLevelTotalTermEvaluator(expressionString);
}
}
return new PCCasterLevelTotalTermEvaluator(expressionString);
}
},
COMPLETE_PC_COUNT_ATTACKS
("COUNT\\[ATTACKS\\]",
new String[] { "COUNT[ATTACKS]" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCCountAttacksTermEvaluator(expressionString);
}
},
COMPLETE_PC_COUNT_CHECKS
("COUNT\\[CHECKS\\]",
new String[] { "COUNT[CHECKS]" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCCountChecksTermEvaluator(expressionString);
}
},
COMPLETE_PC_COUNT_CLASSES
("COUNT\\[CLASSES\\]",
new String[] { "COUNT[CLASSES]" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCCountClassesTermEvaluator(expressionString);
}
},
COMPLETE_PC_COUNT_CONTAINERS
("COUNT\\[CONTAINERS\\]",
new String[] { "COUNT[CONTAINERS]" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCCountContainersTermEvaluator(expressionString);
}
},
COMPLETE_PC_COUNT_DOMAINS
("COUNT\\[DOMAINS\\]",
new String[] { "COUNT[DOMAINS]" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCCountDomainsTermEvaluator(expressionString);
}
},
COMPLETE_PC_COUNT_FEATSNATUREALL
("COUNT\\[FEATSALL(?:\\.ALL|\\.HIDDEN|\\.VISIBLE)?\\]",
new String[] { "COUNT[FEATSALL]",
"COUNT[FEATSALL.ALL]",
"COUNT[FEATSALL.HIDDEN]",
"COUNT[FEATSALL.VISIBLE]"},
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
boolean visible = !(expressionString.endsWith("HIDDEN]"));
boolean hidden = (expressionString.endsWith("HIDDEN]") ||
expressionString.endsWith(".ALL]"));
AbilityCategory abCat = AbilityCategory.FEAT;
return new PCCountAbilitiesNatureAllTermEvaluator(
expressionString,
abCat,
visible,
hidden);
}
},
COMPLETE_PC_COUNT_FEATSNATUREAUTO
("COUNT\\[FEATSAUTO(?:\\.ALL|\\.HIDDEN|\\.VISIBLE)?\\]",
new String[] { "COUNT[FEATSAUTO]",
"COUNT[FEATSAUTO.ALL]",
"COUNT[FEATSAUTO.HIDDEN]",
"COUNT[FEATSAUTO.VISIBLE]"},
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
boolean visible = !(expressionString.endsWith("HIDDEN]"));
boolean hidden = (expressionString.endsWith("HIDDEN]") ||
expressionString.endsWith("ALL]"));
AbilityCategory abCat = AbilityCategory.FEAT;
return new PCCountAbilitiesNatureAutoTermEvaluator(
expressionString,
abCat,
visible,
hidden);
}
},
COMPLETE_PC_COUNT_FEATSNATURENORMAL
("COUNT\\[FEATS(?:\\.ALL|\\.HIDDEN|\\.VISIBLE)?\\]",
new String[] { "COUNT[FEATS]",
"COUNT[FEATS.ALL]",
"COUNT[FEATS.HIDDEN]",
"COUNT[FEATS.VISIBLE]"},
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
boolean visible = !(expressionString.endsWith("HIDDEN]"));
boolean hidden = (expressionString.endsWith("HIDDEN]") ||
expressionString.endsWith("ALL]"));
AbilityCategory abCat = AbilityCategory.FEAT;
return new PCCountAbilitiesNatureNormalTermEvaluator(
expressionString,
abCat,
visible,
hidden);
}
},
COMPLETE_PC_COUNT_FEATSNATUREVIRTUAL
("COUNT\\[VFEATS(?:\\.ALL|\\.HIDDEN|\\.VISIBLE)?\\]",
new String[] { "COUNT[VFEATS]",
"COUNT[VFEATS.ALL]",
"COUNT[VFEATS.HIDDEN]",
"COUNT[VFEATS.VISIBLE]"},
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
boolean visible = !(expressionString.endsWith("HIDDEN]"));
boolean hidden = (expressionString.endsWith("HIDDEN]") ||
expressionString.endsWith("ALL]"));
AbilityCategory abCat = AbilityCategory.FEAT;
return new PCCountAbilitiesNatureVirtualTermEvaluator(
expressionString,
abCat,
visible,
hidden);
}
},
COMPLETE_PC_COUNT_FOLLOWERS
("COUNT\\[FOLLOWERS\\]",
new String[] { "COUNT[FOLLOWERS]" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCCountFollowersTermEvaluator(expressionString);
}
},
COMPLETE_PC_COUNT_LANGUAGES
("COUNT\\[LANGUAGES\\]",
new String[] { "COUNT[LANGUAGES]" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCCountLanguagesTermEvaluator(expressionString);
}
},
COMPLETE_PC_COUNT_MISC_COMPANIONS
("COUNT\\[MISC\\.COMPANIONS\\]",
new String[] { "COUNT[MISC.COMPANIONS]" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCCountMiscCompanionsTermEvaluator(expressionString);
}
},
COMPLETE_PC_COUNT_MISC_FUNDS
("COUNT\\[MISC\\.FUNDS\\]",
new String[] { "COUNT[MISC.FUNDS]" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCCountMiscFundsTermEvaluator(expressionString);
}
},
COMPLETE_PC_COUNT_MISC_MAGIC
("COUNT\\[MISC\\.MAGIC\\]",
new String[] { "COUNT[MISC.MAGIC]" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCCountMiscMagicTermEvaluator(expressionString);
}
},
COMPLETE_PC_COUNT_MOVE
("COUNT\\[MOVE\\]",
new String[] { "COUNT[MOVE]" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCCountMoveTermEvaluator(expressionString);
}
},
COMPLETE_PC_COUNT_NOTES
("COUNT\\[NOTES\\]",
new String[] { "COUNT[NOTES]" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCCountNotesTermEvaluator(expressionString);
}
},
COMPLETE_PC_COUNT_RACESUBTYPES
("COUNT\\[RACESUBTYPES\\]",
new String[] { "COUNT[RACESUBTYPES]" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCCountRaceSubTypesTermEvaluator(expressionString);
}
},
COMPLETE_PC_COUNT_SA
("COUNT\\[SA\\]",
new String[] { "COUNT[SA]" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCCountSABTermEvaluator(expressionString);
}
},
COMPLETE_PC_COUNT_SKILLS
("COUNT\\[SKILLS(?:\\.SELECTED|\\.RANKS|\\.NONDEFAULT|\\.USABLE|\\.ALL)?\\]",
new String[] { "COUNT[SKILLS]",
"COUNT[SKILLS.SELECTED]",
"COUNT[SKILLS.RANKS]",
"COUNT[SKILLS.NONDEFAULT]",
"COUNT[SKILLS.USABLE]",
"COUNT[SKILLS.ALL]"},
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
String filterToken = null;
int start = expressionString.indexOf('.');
if (start > 0)
{
int end = expressionString.indexOf(']', start);
filterToken = expressionString.substring(start + 1, end);
}
return new PCCountSkillsTermEvaluator(expressionString,
filterToken);
}
},
COMPLETE_PC_COUNT_SPELLCLASSES
("COUNT\\[SPELLCLASSES\\]",
new String[] { "COUNT[SPELLCLASSES]" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCCountSpellClassesTermEvaluator(expressionString);
}
},
COMPLETE_PC_COUNT_SPELLRACE
("COUNT\\[SPELLRACE\\]",
new String[] { "COUNT[SPELLRACE]" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCCountSpellRaceTermEvaluator(expressionString);
}
},
COMPLETE_PC_COUNT_STATS
("COUNT\\[STATS\\]",
new String[] { "COUNT[STATS]" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCCountStatsTermEvaluator(expressionString);
}
},
COMPLETE_PC_COUNT_TEMPBONUSNAMES
("COUNT\\[TEMPBONUSNAMES\\]",
new String[] { "COUNT[TEMPBONUSNAMES]" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCCountTempBonusNamesTermEvaluator(expressionString);
}
},
COMPLETE_PC_COUNT_TEMPLATES
("COUNT\\[TEMPLATES\\]",
new String[] { "COUNT[TEMPLATES]" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCCountTemplatesTermEvaluator(expressionString);
}
},
COMPLETE_PC_COUNT_VISIBLETEMPLATES
("COUNT\\[VISIBLETEMPLATES\\]",
new String[] { "COUNT[VISIBLETEMPLATES]" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCCountVisibleTemplatesTermEvaluator(expressionString);
}
},
COMPLETE_PC_COUNT_VISION
("COUNT\\[VISION\\]",
new String[] { "COUNT[VISION]" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCCountVisionTermEvaluator(expressionString);
}
},
COMPLETE_PC_ENCUMBERANCE
("ENCUMBERANCE",
new String[] { "ENCUMBERANCE" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCEncumberanceTermEvaluator(expressionString);
}
},
COMPLETE_PC_HD
("HD",
new String[] { "HD" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCHDTermEvaluator(expressionString);
}
},
COMPLETE_PC_HP
("HP",
new String[] { "HP" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCHPTermEvaluator(expressionString);
}
},
COMPLETE_PC_MAXCASTABLE
("MAXCASTABLE",
new String[] { "MAXCASTABLE" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
if (src.startsWith("CLASS:"))
{
return new PCMaxCastableClassTermEvaluator(
expressionString,
src.substring(6));
}
else if (src.startsWith("DOMAIN:"))
{
return new PCMaxCastableDomainTermEvaluator(
expressionString,
src.substring(7));
}
else if (src.startsWith("SPELLTYPE:"))
{
return new PCMaxCastableSpellTypeTermEvaluator(
expressionString,
src.substring(10));
}
else if ("ANY".equals(src))
{
return new PCMaxCastableAnyTermEvaluator(
expressionString);
}
StringBuilder sB = new StringBuilder();
sB.append("MAXCASTABLE is not usable in ");
sB.append(src);
throw new TermEvaulatorException(sB.toString());
}
},
COMPLETE_PC_MOVEBASE
("MOVEBASE",
new String[] { "MOVEBASE" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCMoveBaseTermEvaluator(expressionString);
}
},
COMPLETE_PC_PC_HEIGHT
("PC\\.HEIGHT",
new String[] { "PC.HEIGHT" },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCHeightTermEvaluator(expressionString);
}
},
COMPLETE_PC_PC_WEIGHT
("PC\\.WEIGHT",
new String[] { "PC.WEIGHT" },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCWeightTermEvaluator(expressionString);
}
},
COMPLETE_PC_PROFACCHECK
("PROFACCHECK",
new String[] { "PROFACCHECK" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
String source = (src.startsWith("EQ:")) ? src.substring(3) : "";
return new PCProfACCheckTermEvaluator(
expressionString,
source);
}
},
COMPLETE_PC_RACESIZE
("RACESIZE",
new String[] { "RACESIZE" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCRaceSizeTermEvaluator(expressionString);
}
},
COMPLETE_PC_RACIALHDSIZE
("RACIALHDSIZE",
new String[] { "RACIALHDSIZE" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCRacialHDSizeTermEvaluator(expressionString);
}
},
COMPLETE_PC_SCORE
("SCORE",
new String[] { "SCORE" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
try
{
int i = Integer.parseInt(src);
return new FixedTermEvaluator(i);
}
catch (NumberFormatException e)
{
//OK
}
String source = (src.startsWith("STAT:")) ? src.substring(5) : "";
return new PCScoreTermEvaluator(expressionString, source);
}
},
COMPLETE_PC_SHIELDACCHECK
("SHIELDAC{1,2}HECK",
new String[] { "SHIELDACCHECK", "SHIELDACHECK" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCShieldACcheckTermEvaluator(expressionString);
}
},
COMPLETE_PC_SIZEMOD
("SIZEMOD|SIZE",
new String[] { "SIZEMOD", "SIZE" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
if ("SIZEMOD".equals(matchedSection))
{
return new PCSizeModEvaluatorTermEvaluator(expressionString);
}
else
{
return new PCSizeTermEvaluator(expressionString);
}
}
},
COMPLETE_PC_SPELLBASESTAT
("SPELLBASESTATSCORE|SPELLBASESTAT",
new String[] { "SPELLBASESTAT", "SPELLBASESTATSCORE" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
String source = (src.startsWith("CLASS:")) ? src.substring(6) : "";
if (expressionString.endsWith("SCORE"))
{
return new PCSPellBaseStatScoreEvaluatorTermEvaluator(expressionString, source);
}
return new PCSPellBaseStatTermEvaluator(expressionString, source);
}
},
COMPLETE_PC_SPELLLEVEL
("SPELLLEVEL",
new String[] { "SPELLLEVEL" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCSpellLevelTermEvaluator(expressionString);
}
},
COMPLETE_PC_TL
("TL",
new String[] { "TL" },
true) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCTLTermEvaluator(expressionString);
}
},
COMPLETE_PC_FAVCLASSLEVEL
("FAVCLASSLEVEL",
new String[]{"FAVCLASSLEVEL"},
true) {
@Override
public TermEvaluator getTermEvaluator(final String expressionString,
final String src, final String matchedSection)
{
return new PCFavClassLevelTermEvaluator(expressionString);
}
},
PC_CAST_ATWILL
("ATWILL",
new String[]{"ATWILL"},
true) {
@Override
public TermEvaluator getTermEvaluator(final String expressionString,
final String src, final String matchedSection)
{
return new PCCastTimesAtWillTermEvaluator(expressionString);
}
},
START_PC_BL
("BL[.=]?",
new String[] { "BL.", "BL=", "BL" },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
String classString;
if (matchedSection.length() == expressionString.length())
{
classString = (src.startsWith("CLASS:")) ? src.substring(6) : "";
}
else
{
classString = expressionString.substring(matchedSection.length());
}
return new PCBLTermEvaluator(
expressionString,
classString);
}
},
START_PC_CL_BEFORELEVEL
("CL;BEFORELEVEL[.=]",
new String[] { "CL;BEFORELEVEL.", "CL;BEFORELEVEL=" },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
if (!src.startsWith("CLASS:")) {
StringBuilder sB = new StringBuilder();
sB.append(matchedSection);
sB.append(" may only be used in a Class");
throw new TermEvaulatorException(sB.toString());
}
int i;
try
{
i = Integer.parseInt(expressionString.substring(15));
}
catch (NumberFormatException e)
{
StringBuilder sB = new StringBuilder();
sB.append("Badly formed formula ");
sB.append(expressionString);
sB.append(" in ");
sB.append(src);
sB.append(" should have an integer following ");
sB.append(matchedSection);
throw new TermEvaulatorException(sB.toString());
}
return new PCCLBeforeLevelTermEvaluator(
expressionString,
src.substring(6),
i);
}
},
START_PC_CLASSLEVEL
("CLASSLEVEL[.=]",
new String[] { "CLASSLEVEL.", "CLASSLEVEL=" },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
String exp = expressionString.replace('{', '(').replace('}', ')');
String classString = exp.substring(11);
return new PCCLTermEvaluator(
expressionString,
classString);
}
},
START_PC_CLASS
("CLASS[.=]",
new String[] { "CLASS.", "CLASS=" },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
return new PCHasClassTermEvaluator(
expressionString,
expressionString.substring(6));
}
},
START_PC_CL
("CL[.=]?",
new String[] { "CL.", "CL=", "CL" },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
String classString;
if (2 == expressionString.length())
{
if (!src.startsWith("CLASS:")) {
StringBuilder sB = new StringBuilder();
sB.append(matchedSection);
sB.append(" may only be used in a Class");
throw new TermEvaulatorException(sB.toString());
}
classString = (src.startsWith("CLASS:")) ? src.substring(6) : "";
}
else
{
classString = expressionString.substring(3);
}
return new PCCLTermEvaluator(
expressionString,
classString);
}
},
START_PC_COUNT_EQTYPE
("COUNT\\[EQTYPE\\.?",
new String[] { "COUNT[EQTYPE", "COUNT[EQTYPE." },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
// The types string inside the brackets
String typesString =
TermUtilities.extractContentsOfBrackets(
expressionString,
src,
matchedSection.length());
// In the case of the empty string, the split will give us a one
// element array containing only the empty string (which is the
// desired result)
String[] fullTypes = typesString.split("\\.", -1);
int merge = "MERGENONE".equals(fullTypes[0]) ? Constants.MERGE_NONE :
"MERGELOC".equals(fullTypes[0]) ? Constants.MERGE_LOCATION :
Constants.MERGE_ALL;
int first = (Constants.MERGE_ALL == merge) ? 0 : 1;
String[] types;
if (fullTypes.length > first) {
TermUtilities.checkEqTypeTypesArray(
expressionString,
fullTypes,
first);
int len = fullTypes.length - first;
types = new String[len];
System.arraycopy(fullTypes, first, types, 0, len);
}
else
{
types = new String[] {""};
}
return new PCCountEqTypeTermEvaluator(
expressionString,
types,
merge);
}
},
START_PC_COUNT_EQUIPMENT
("COUNT\\[EQUIPMENT\\.?",
new String[] { "COUNT[EQUIPMENT.", "COUNT[EQUIPMENT" },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
// The types string inside the brackets
String typesString =
TermUtilities.extractContentsOfBrackets(
expressionString,
src,
matchedSection.length());
// In the case of the empty string, the split will give us a one
// element array containing only the empty string (which is the
// desired result)
String[] fullTypes = typesString.split("\\.");
int merge = "MERGENONE".equals(fullTypes[0]) ? Constants.MERGE_NONE :
"MERGELOC".equals(fullTypes[0]) ? Constants.MERGE_LOCATION :
Constants.MERGE_ALL;
int first = (Constants.MERGE_ALL == merge) ? 0 : 1;
String[] types;
if (fullTypes.length > first) {
TermUtilities.checkEquipmentTypesArray(
expressionString,
fullTypes,
first);
int len = fullTypes.length - first;
types = new String[len];
System.arraycopy(fullTypes, first, types, 0, len);
} else {
types = new String[] {""};
}
return new PCCountEquipmentTermEvaluator(
expressionString,
types,
merge);
}
},
START_PC_COUNT_FEATTYPE
("COUNT\\[(?:FEATAUTOTYPE|FEATNAME|FEATTYPE|VFEATTYPE)[.=]",
new String[] { "COUNT[FEATAUTOTYPE.", "COUNT[FEATAUTOTYPE=",
"COUNT[FEATNAME.", "COUNT[FEATNAME=",
"COUNT[FEATTYPE.", "COUNT[FEATTYPE=",
"COUNT[VFEATTYPE.", "COUNT[VFEATTYPE=" },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
Matcher subtokenMat = subtokenPat.matcher(expressionString);
if (!subtokenMat.find())
{
StringBuilder sB = new StringBuilder();
sB.append("Impossible error while parsing \"");
sB.append(expressionString);
sB.append("\" in ");
sB.append(src);
throw new TermEvaulatorException(sB.toString());
}
int start = expressionString.startsWith("COUNT[FEATA") ? 19 :
expressionString.startsWith("COUNT[V") ? 16 : 15;
// The types string inside the brackets
String typesString =
TermUtilities.extractContentsOfBrackets(expressionString, src, start);
// In the case of the empty string, the split will give us a one
// element array containing only the empty string (which is the
// desired result)
String[] types = typesString.split("\\.", -1);
boolean visible = !(expressionString.endsWith("HIDDEN]"));
boolean hidden = (expressionString.endsWith("HIDDEN]") ||
expressionString.endsWith("ALL]"));
if ("ALL".equals(types[types.length - 1]) ||
"HIDDEN".equals(types[types.length - 1]) ||
"VISIBLE".equals(types[types.length - 1]))
{
if (types.length > 1)
{
int len = types.length - 1;
String[] t = new String[len];
System.arraycopy(types, 0, t, 0, len);
types = t;
}
else
{
types = new String[] {""};
}
}
AbilityCategory abCat = AbilityCategory.FEAT;
if ("FEATAUTOTYPE".equals(subtokenMat.group()))
{
return new PCCountAbilitiesTypeNatureAutoTermEvaluator(
expressionString,
abCat,
types,
visible,
hidden);
}
else if ("FEATNAME".equals(subtokenMat.group()))
{
return new PCCountAbilityNameTermEvaluator(
expressionString,
abCat,
types[0],
visible,
hidden);
}
else if ("FEATTYPE".equals(subtokenMat.group()))
{
return new PCCountAbilitiesTypeNatureAllTermEvaluator(
expressionString,
abCat,
types,
visible,
hidden);
}
else
{
return new PCCountAbilitiesTypeNatureVirtualTermEvaluator(
expressionString,
abCat,
types,
visible,
hidden);
}
}
},
START_PC_COUNT_FOLLOWERTYPE
("COUNT\\[FOLLOWERTYPE\\.",
new String[] { "COUNT[FOLLOWERTYPE." },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
// The types string inside the brackets
String typesString =
TermUtilities.extractContentsOfBrackets(expressionString, src, 19);
String[] types = typesString.split("\\.", 3);
if (types.length == 1)
{
// This covers COUNT[FOLLOWERTYPE.Animal Companions] syntax
return new PCCountFollowerTypeTermEvaluator(
expressionString,
types[0]);
}
else if (types.length == 2)
{
StringBuilder sB = new StringBuilder();
sB.append("Badly formed formula ");
sB.append(expressionString);
sB.append(" in ");
sB.append(src);
throw new TermEvaulatorException(sB.toString());
}
else
{
Matcher numMat = numPat.matcher(types[1]);
if (!numMat.find())
{
StringBuilder sB = new StringBuilder();
sB.append("Badly formed formula ");
sB.append(expressionString);
sB.append(" in ");
sB.append(src);
throw new TermEvaulatorException(sB.toString());
}
String newCount = "COUNT[" + types[2] + "]";
// This will do COUNT[FOLLOWERTYPE.Animal Companions.0.xxx],
// returning the same as COUNT[xxx] if applied to the right follower
return new PCCountFollowerTypeTransitiveTermEvaluator(
expressionString,
types[0],
Integer.valueOf(numMat.group()),
newCount);
}
}
},
START_PC_COUNT_SKILLTYPE
("COUNT\\[SKILLTYPE[.=]",
new String[] { "COUNT[SKILLTYPE.", "COUNT[SKILLTYPE=" },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
String type = TermUtilities.extractContentsOfBrackets(expressionString, src, 16);
return new PCSkillTypeTermEvaluator(
expressionString,
type);
}
},
START_PC_COUNT_SPELLBOOKS
("COUNT\\[SPELLBOOKS",
new String[] { "COUNT[SPELLBOOKS" },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
TermUtilities.extractContentsOfBrackets(expressionString, src, 16);
return new PCCountSpellbookTermEvaluator(
expressionString);
}
},
START_PC_COUNT_SPELLSINBOOK
("COUNT\\[SPELLSINBOOK",
new String[] { "COUNT[SPELLSINBOOK" },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
return new PCCountSpellsInbookTermEvaluator(
expressionString,
TermUtilities.extractContentsOfBrackets(expressionString, src, 19));
}
},
START_PC_COUNT_SPELLSKNOWN
("COUNT\\[SPELLSKNOWN",
new String[] { "COUNT[SPELLSKNOWN" },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
// The spells string inside the brackets
String spellsString =
TermUtilities.extractContentsOfBrackets(expressionString, src, 17);
// make an array with one element in case we need it in the
// catch block. The string could legitimatey be empty in which
// case a numberFormatException will be thrown
int[] nums = { -1 };
if (spellsString.length() > 1 && spellsString.startsWith("."))
{
String s = spellsString.substring(1);
try
{
nums = TermUtilities.convertToIntegers(
expressionString,
s,
matchedSection.length(),
2);
}
catch (NumberFormatException e)
{
// the -1 means get them all (i.e. no filtering by class
// or spellbook)
nums[0] = -1;
}
}
return new PCCountSpellsKnownTermEvaluator(
expressionString,
nums);
}
},
START_PC_COUNT_SPELLSLEVELSINBOOK
("COUNT\\[SPELLSLEVELSINBOOK",
new String[] { "COUNT[SPELLSLEVELSINBOOK" },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
String intString =
TermUtilities.extractContentsOfBrackets(
expressionString,
src,
24);
int[] nums = new int[] {-1};
if (intString.length() > 1 && intString.startsWith("."))
{
String s = intString.substring(1);
try
{
nums = TermUtilities.convertToIntegers(
expressionString,
s,
matchedSection.length(),
2);
}
catch (NumberFormatException e)
{
// the -1 means get them all (i.e. no filtering by class
// or spellbook)
nums[0] = -1;
}
}
else
{
StringBuilder sB = new StringBuilder();
sB.append("Badly formed formula ");
sB.append(expressionString);
sB.append(" following ");
sB.append(matchedSection);
sB.append(" should be 2 ");
sB.append("integers separated by dots");
throw new TermEvaulatorException(sB.toString());
}
return new PCCountSpellsLevelsInBookTermEvaluator(
expressionString, nums);
}
},
START_PC_COUNT_SPELLTIMES
("COUNT\\[SPELLTIMES",
new String[] { "COUNT[SPELLTIMES" },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
String intString =
TermUtilities.extractContentsOfBrackets(expressionString, src, 16);
int[] nums = new int[] {-1};
if (intString.length() > 1 && intString.startsWith("."))
{
String s = intString.substring(1);
try
{
nums = TermUtilities.convertToIntegers(
expressionString,
s,
matchedSection.length(),
4);
}
catch (NumberFormatException e)
{
// the -1 means get them all (i.e. no filtering by class
// or spellbook)
nums[0] = -1;
}
}
else
{
StringBuilder sB = new StringBuilder();
sB.append("Badly formed formula ");
sB.append(expressionString);
sB.append(" following ");
sB.append(matchedSection);
sB.append(" should be 4 ");
sB.append("integers separated by dots");
throw new TermEvaulatorException(sB.toString());
}
return new PCCountSpellTimesTermEvaluator(
expressionString,
nums);
}
},
START_PC_EQTYPE
("EQTYPE",
new String[] { "EQTYPE" },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
return new PCEqTypeTermEvaluator(expressionString);
}
},
START_PC_HASDEITY
("HASDEITY:",
new String[] { "HASDEITY:" },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
return new PCHasDeityTermEvaluator(
expressionString,
expressionString.substring(9));
}
},
START_PC_HASFEAT
("HASFEAT:",
new String[] { "HASFEAT:" },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
return new PCHasFeatTermEvaluator(
expressionString,
expressionString.substring(8));
}
},
START_PC_MAXLEVEL("MAXLEVEL", new String[]{"MAXLEVEL"}, true) {
@Override
public TermEvaluator getTermEvaluator(final String expressionString,
final String src, final String matchedSection)
{
if (src.startsWith("CLASS:") || src.startsWith("CLASS|"))
{
return new PCMaxLevelTermEvaluator(expressionString, src.substring(6));
}
else
{
Logging.errorPrint("MAXLEVEL term called without a CLASS source");
return new PCMaxLevelTermEvaluator(expressionString, "");
}
}
},
START_PC_MODEQUIP
("MODEQUIP",
new String[] { "MODEQUIP" },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
return new PCModEquipTermEvaluator(
expressionString,
expressionString.substring(8));
}
},
START_PC_MOVE
("MOVE\\[",
new String[] { "MOVE[" },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
return new PCMovementTermEvaluator(
expressionString,
TermUtilities.extractContentsOfBrackets(expressionString, src, 5));
}
},
START_PC_PC_SIZE
("PC\\.SIZE(?:\\.INT)?",
new String[] { "PC.SIZE.INT", "PC.SIZE" },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
if (matchedSection.length() == 11)
{
if (src.startsWith("EQ:"))
{
return new PCSizeIntEQTermEvaluator(
expressionString,
src.substring(3));
}
else
{
return new PCSizeIntTermEvaluator(expressionString);
}
}
else
{
return new PCSizeTermEvaluator(expressionString);
}
}
},
START_PC_SKILLRANK
("SKILLRANK[.=]",
new String[] { "SKILLRANK.", "SKILLRANK=" },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
String skillString =
expressionString.substring(10)
.replace('{', '(').replace('}', ')');
return new PCSkillRankTermEvaluator(
expressionString,
skillString);
}
},
START_PC_SKILLTOTAL
("SKILLTOTAL[.=]",
new String[] { "SKILLTOTAL.", "SKILLTOTAL=" },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
String skillString =
expressionString.substring(11)
.replace('{', '(').replace('}', ')');
return new PCSkillTotalTermEvaluator(
expressionString,
skillString);
}
},
START_PC_VARDEFINED
("VARDEFINED:",
new String[] { "VARDEFINED:" },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
String varString = expressionString.substring(11);
return new PCVarDefinedTermEvaluator(
expressionString,
varString);
}
},
START_PC_WEIGHT
("WEIGHT\\.",
new String[] { "WEIGHT." },
false) {
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) throws TermEvaulatorException
{
// The type of weight we want the value for
String valString = expressionString.substring(7);
if ("CARRIED".equals(valString))
{
return new PCCarriedWeightTermEvaluator(expressionString);
}
else if ("EQUIPPED".equals(valString))
{
// TODO: not carried, equipped!
return new PCCarriedWeightTermEvaluator (expressionString);
}
else if ("PC".equals(valString))
{
return new PCWeightTermEvaluator(expressionString);
}
else if ("TOTAL".equals(valString))
{
// total weight of PC and all carried equipment
return new PCTotalWeightTermEvaluator(expressionString);
}
StringBuilder sB = new StringBuilder();
sB.append("invalid string following WEIGHT. in ");
sB.append(expressionString);
throw new TermEvaulatorException(sB.toString());
}
},
COMPLETE_PC_BONUSLANG("BONUSLANG", new String[] { "BONUSLANG" }, true)
{
@Override
public TermEvaluator getTermEvaluator(final String expressionString,
final String src, final String matchedSection)
{
return new PCBonusLangTermEvaluator(expressionString);
}
},
COMPLETE_PC_HANDS("HANDS", new String[] { "HANDS" }, true)
{
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCHandsTermEvaluator(expressionString);
}
},
COMPLETE_PC_LEGS("LEGS", new String[] { "LEGS" }, true)
{
@Override
public TermEvaluator getTermEvaluator(
final String expressionString,
final String src,
final String matchedSection) {
return new PCLegsTermEvaluator(expressionString);
}
};
static final String subtokenString = "(FEATAUTOTYPE|FEATNAME|FEATTYPE|VFEATTYPE)";
static final Pattern subtokenPat = Pattern.compile(subtokenString);
static final Pattern numPat = Pattern.compile("\\d+");
private final String termConstructorPattern;
private final String[] termConstructorKeys;
private final boolean patternMatchesEntireTerm;
TermEvaluatorBuilderPCVar(
String pattern,
String[] keys,
boolean matchEntireTerm)
{
termConstructorPattern = pattern;
termConstructorKeys = keys;
patternMatchesEntireTerm = matchEntireTerm;
}
@Override
public String getTermConstructorPattern()
{
return termConstructorPattern;
}
@Override
public String[] getTermConstructorKeys()
{
return termConstructorKeys;
}
@Override
public boolean isEntireTerm()
{
return patternMatchesEntireTerm;
}
}