/* * GameMode.java * Copyright 2001 (C) Greg Bingleman <byngl@hotmail.com> * * 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 on September 22, 2002, 4:30 PM * * Current Ver: $Revision$ * */ package pcgen.core; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedMap; import java.util.StringTokenizer; import java.util.TreeMap; import java.util.TreeSet; import org.apache.commons.lang3.StringUtils; import pcgen.base.util.HashMapToList; import pcgen.cdom.base.CDOMReference; import pcgen.cdom.base.Categorized; import pcgen.cdom.base.Constants; import pcgen.cdom.base.Loadable; import pcgen.cdom.base.MasterListInterface; import pcgen.cdom.content.ACControl; import pcgen.cdom.content.RollMethod; import pcgen.cdom.content.TabInfo; import pcgen.cdom.reference.CDOMSingleRef; import pcgen.cdom.reference.ReferenceManufacturer; import pcgen.cdom.reference.TransparentCategorizedReferenceManufacturer; import pcgen.cdom.reference.TransparentReference; import pcgen.core.character.WieldCategory; import pcgen.core.system.LoadInfo; import pcgen.facade.core.GameModeFacade; import pcgen.rules.context.AbstractReferenceContext; import pcgen.rules.context.ConsolidatedListCommitStrategy; import pcgen.rules.context.GameReferenceContext; import pcgen.rules.context.LoadContext; import pcgen.rules.context.RuntimeLoadContext; import pcgen.rules.context.RuntimeReferenceContext; import pcgen.rules.context.TrackingReferenceContext; import pcgen.system.PCGenSettings; import pcgen.system.PropertyContext; import pcgen.util.ComparableComparator; import pcgen.util.Logging; import pcgen.util.enumeration.Tab; /** * Handles game modes. * * @author Greg Bingleman <byngl@hotmail.com> */ public final class GameMode implements Comparable<Object>, GameModeFacade { private static PropertyContext prefsContext = PCGenSettings.getInstance().createChildContext("gameMode"); //$NON-NLS-1$ private PropertyContext gamemodePrefsContext = prefsContext.createChildContext("gameMode"); //$NON-NLS-1$ private List<String> allowedModes; private List<String> bonusFeatLevels = new ArrayList<>(); private List<String> bonusStackList = new ArrayList<>(); private List<String> bonusStatLevels = new ArrayList<>(); private List<ClassType> classTypeList = new ArrayList<>(); private List<String> defaultDataSetList = new ArrayList<>(); private List<String> defaultDeityList = new ArrayList<>(); private Map<String, XPTable> xpTableInfo = new HashMap<>(); private List<String> loadStrings = new ArrayList<>(); private List<String> skillMultiplierLevels = new ArrayList<>(); @Deprecated private HashMapToList<String, ACControl> ACTypeAddMap = new HashMapToList<>(); @Deprecated private HashMapToList<String, ACControl> ACTypeRemoveMap = new HashMapToList<>(); private Map<String, String> plusCalcs; private Map<String, String> spellRangeMap = new HashMap<>(); private String acAbbrev = ""; private String acName = ""; private String alignmentName = ""; private String althpAbbrev = ""; private String althpName = ""; private String babAbbrev = null; private String currencyUnit = ""; private String currencyUnitAbbrev = ""; private String damageResistance = ""; private String defaultSpellBook = "Known Spells"; private String defaultUnitSet = Constants.STANDARD_UNITSET_NAME; private UnitSet selectedUnitSet = null; private String displayName = ""; private String displayVariable2Name = ""; private String displayVariable2Text = ""; private String displayVariable3Name = ""; private String displayVariable3Text = ""; private String displayVariableName = ""; private String displayVariableText = ""; private String folderName = ""; private String hpAbbrev = ""; private String hpName = ""; private String levelUpMessage = ""; private String menuToolTip = ""; private String name = ""; private String spellBaseDC = "0"; private String spellBaseConcentration = ""; private String wcStepsFormula = ""; private String weaponCategories = ""; private String weaponTypes = ""; private String weaponReachFormula = ""; private Map<Integer, Integer> xpAwardsMap = new HashMap<>(); private Map<Integer, String> crStepsMap = new HashMap<>(); private String crThreshold = null; private String rankModFormula = ""; private String addWithMetamagic = ""; private boolean allowAutoResize = false; private boolean bonusStatAllowsStack = false; private boolean showClassDefense; private int babAttCyc = 5; //6 private int babMaxAtt = Integer.MAX_VALUE; //4 private int babMaxLvl = Integer.MAX_VALUE; //20 private int babMinVal = 1; private int maxNonEpicLevel = Integer.MAX_VALUE; private int checksMaxLvl = Integer.MAX_VALUE; //20 private int displayOrder = Integer.MAX_VALUE; private final List<String> schoolsList = new ArrayList<>(20); private int skillCosts_Class = 1; private int skillCost_CrossClass = 2; private int skillCost_Exclusive = 0; private String pointPoolName = ""; private String hpFormula = ""; private int nonProfPenalty = -4; private double squareSize = 5; /** no default distance for short range */ private int shortRangeDistance; private int rangePenalty; private RollMethod activeRollMethod = null; private SortedMap<Integer, PointBuyCost> pointBuyStatCosts = null; private int[] abilityScoreCost = null; private String purchaseMethodName = ""; //$NON-NLS-1$ private int rollMethod = Constants.CHARACTER_STAT_METHOD_USER; private int allStatsValue = 10; // // minimum and maximum stat values when creating new characters. // private int statMin = 3; private int statMax = 18; private TreeMap<Integer, String> statDisplayText = null; private String statDisplayTextAppend = "+"; private TreeMap<Integer, String> skillRankDisplayText = null; private String thePreviewDir; private String theDefaultPreviewSheet; private String theInfoSheet; private String theInfoSheetSkill; private String outputSheetDirectory; private Map<String, String> outputSheetDefaultMap = new HashMap<>(); private int [] dieSizes; private int maxDieSize = 12; private int minDieSize = 4; private List<String> resizableTypeList = new ArrayList<>(); private List<String> characterTypeList = new ArrayList<>(); private List<String> monsterRoleList = new ArrayList<>(); private String monsterRoleDefault = ""; private Map<Class<?>, Set<String>> hiddenTypes = new HashMap<>(); private List<String> xpTableNames = new ArrayList<>(); private String defaultXPTableName; private String defaultCharacterType; /** The BioSet used for age calculations */ private BioSet bioSet = new BioSet(); /** SHOWTAB compatibility */ private Map<CDOMSingleRef<TabInfo>, Boolean> visibleTabs; private Map<String, String> equipTypeIconMap = new HashMap<>(); /** Priority of the equipment types for icon use. */ private Map<String, Integer> equipTypeIconPriorityMap = new HashMap<>(); /** A container for feat settings for this game mode. */ private AbilityCategory featTemplate; /** * Creates a new instance of GameMode. * * @param modeName the mode name */ public GameMode(final String modeName) { name = modeName; folderName = modeName; displayName = modeName; thePreviewDir = modeName; theDefaultPreviewSheet = "preview.html"; //$NON-NLS-1$ } /** * Apply the stored preferences to the game mode. */ public void applyPreferences() { gamemodePrefsContext = prefsContext.createChildContext(name); String rollMethodExpr = gamemodePrefsContext.getProperty("rollMethodExpression"); //$NON-NLS-1$ if (StringUtils.isNotBlank(rollMethodExpr)) { activeRollMethod = getModeContext().getReferenceContext().silentlyGetConstructedCDOMObject( RollMethod.class, rollMethodExpr); if (activeRollMethod == null) { Logging.errorPrint("Could not find roll method '" //$NON-NLS-1$ + rollMethodExpr + "' while loading game mode " + name); //$NON-NLS-1$ } } rollMethod = gamemodePrefsContext.getInt("rollMethod"); //$NON-NLS-1$ allStatsValue = gamemodePrefsContext.initInt("allStatsValue", 10); //$NON-NLS-1$ purchaseMethodName = gamemodePrefsContext.getProperty("purchaseMethodName"); //$NON-NLS-1$ } /** * Set the AC Abbreviation. * @param aString */ public void setACAbbrev(final String aString) { acAbbrev = aString; } /** * Set the AC Text. * @param aString */ public void setACText(final String aString) { acName = aString; } /** * Add the AC Type as a string to the List. * @param ACType * @return List of AC Types */ @Deprecated public List<ACControl> getACTypeAddString(final String ACType) { return ACTypeAddMap.getListFor(ACType); } /** * Remove the AC Type as a string to the List. * @param ACType * @return List of AC Types */ @Deprecated public List<ACControl> getACTypeRemoveString(final String ACType) { return ACTypeRemoveMap.getListFor(ACType); } /** * Retrieve the correct case of the supplied ACType name. * @param acType The name to be found. * @return The name in the correct case. */ @Deprecated public String getACTypeName(String acType) { if (ACTypeAddMap.containsListFor(acType) || ACTypeRemoveMap.containsListFor(acType)) { return acType; } for (String acKey : ACTypeAddMap.getKeySet()) { if (acKey.equalsIgnoreCase(acType)) { return acKey; } } for (String acKey : ACTypeRemoveMap.getKeySet()) { if (acKey.equalsIgnoreCase(acType)) { return acKey; } } return acType; } /** * Set Alignment Text. * @param aString */ public void setAlignmentText(final String aString) { alignmentName = aString; } /** * Set Allowed Game modes. * @param argAllowedModes */ public void setAllowedModes(final String argAllowedModes) { final StringTokenizer aTok = new StringTokenizer(argAllowedModes, "|", false); while (aTok.hasMoreTokens()) { final String aString = aTok.nextToken(); if (allowedModes == null) { allowedModes = new ArrayList<>(); } allowedModes.add(aString); } } /** * Set the alternative HP Abbreviation. * @param aString */ public void setAltHPAbbrev(final String aString) { althpAbbrev = aString; } /** * Set the alternative HP Text. * @param aString */ public void setAltHPText(final String aString) { althpName = aString; } /** * Set flag to allow auto resizing or not. * @param allow */ public void setAllowAutoResize(final boolean allow) { allowAutoResize = allow; } /** * Get the allow auto resize flag. * @return true if allowed to auto resize */ public boolean getAllowAutoResize() { return allowAutoResize; } /** * Set BAB Abbreviation. * @param aString */ public void setBabAbbrev(final String aString) { babAbbrev = aString; } /** * Get BAB Abbreviation. * @return BAB Abbreviation */ public String getBabAbbrev() { return babAbbrev; } /** * Set BAB Minimum value * @param arg */ public void setBabMinVal(final int arg) { babMinVal = arg; } /** * Get BAB Minimum value. * @return BAB Minimum value */ public int getBabMinVal() { return babMinVal; } /** * Set Level at which you gain a bonus stat. * @param aString */ public void setBonusStatLevels(final String aString) { bonusStatLevels.add(aString); } /** * Set Max Level check. * @param arg */ public void setChecksMaxLvl(final int arg) { checksMaxLvl = arg; } /** * Get max level check. * @return max level check */ public int getChecksMaxLvl() { return checksMaxLvl; } /** * Get the class type by name. * @param aClassKey * @return ClassType */ public ClassType getClassTypeByName(final String aClassKey) { for ( ClassType classType : classTypeList ) { if (classType.getName().equalsIgnoreCase(aClassKey)) { return classType; } } return null; } /** * Set the Currency Unit. * @param aString */ public void setCurrencyUnit(final String aString) { currencyUnit = aString; } /** * Set the currency Unit abbreviation. * @param aString */ public void setCurrencyUnitAbbrev(final String aString) { currencyUnitAbbrev = aString; } /** * Set DR text. * @param aString */ public void setDamageResistanceText(final String aString) { damageResistance = aString; } /** * Set the default spell book. * @param aString */ public void setDefaultSpellBook(final String aString) { defaultSpellBook = aString; } /** * Define the default unit set for a game mode. * @param aString */ public void setDefaultUnitSet(final String aString) { defaultUnitSet = aString; } /** * Get the display name of the game mode. * @return displayName */ @Override public String getDisplayName() { return displayName; } /** * Used for Output sheets and GUI to order items in a list. * @param aString */ public void setDisplayOrder(final String aString) { try { displayOrder = Integer.parseInt(aString); } catch (NumberFormatException exc) { Logging.errorPrint("Will use default for displayOrder: " + displayOrder, exc); } } /** * Set the levels at which you gain bonus feats. * @param aString */ public void setBonusFeatLevels(final String aString) { bonusFeatLevels.add(aString); } /** * @return the folderName. */ public String getFolderName() { return folderName; } /** * Set the HP Abbreviation. * @param aString */ public void setHPAbbrev(final String aString) { hpAbbrev = aString; } /** * Set the HP Text. * @param aString */ public void setHPText(final String aString) { hpName = aString; } /** * Set the Rank Modifier Formula. * @param aString */ public void setRankModFormula(final String aString) { rankModFormula = aString; } /** * Obtain a map of LevelInfo objects. * * @param xpTableName the name of the XP table to be used * * @return level info map */ public XPTable getLevelInfo(final String xpTableName) { return xpTableInfo.get(xpTableName); } /** * Add new level info to an XP table. * * @param levInfo */ public void addLevelInfo(final String xpTableName, final LevelInfo levInfo) { XPTable xpTable = xpTableInfo.get(xpTableName); if (xpTable == null) { xpTable = new XPTable(xpTableName); xpTableInfo.put(xpTableName, xpTable); } xpTable.addLevelInfo(levInfo.getLevelString(), levInfo); } /** * Set the level up message. * @param aString */ public void setLevelUpMessage(final String aString) { levelUpMessage = aString; } /** * Get the level up message. * @return the level up message */ public String getLevelUpMessage() { return levelUpMessage; } /** * Get the menu tool tip. * @return menu tool tip */ public String getMenuToolTip() { if (menuToolTip == null) { return ""; } return menuToolTip; } /** * Set the game mode name. * @param modeName The MENUENTRY value. */ public void setModeName(final String modeName) { displayName = modeName; } /** * Set the game mode tool tip. * @param aString */ public void setModeToolTip(final String aString) { menuToolTip = aString; } /** * Get the game mode name. * @return game mode name */ @Override public String getName() { return name; } /** * Set the game mode name (aka key). Should not * be used after game mode is loaded. * @param name the name to set */ public void setName(String name) { this.name = name; } /** * Get Plus calculation. * @param type * @return plus calculation */ public String getPlusCalculation(final String type) { String aString = null; if (plusCalcs != null) { aString = plusCalcs.get(type.toUpperCase()); } return aString; } /** * Set the Short Range distance. * @param aShortRange */ public void setShortRangeDistance(final int aShortRange) { shortRangeDistance = aShortRange; } /** * Get the shortrange distance. * @return the shortrange distance */ public int getShortRangeDistance() { return shortRangeDistance; } /** * Set the show class defense parameter. * @param argShowDef */ public void setShowClassDefense(final boolean argShowDef) { showClassDefense = argShowDef; } /** * Set the skill multiplier levels. * @param pipeList */ public void setSkillMultiplierLevels(final String pipeList) { final StringTokenizer aTok = new StringTokenizer(pipeList, "|", false); skillMultiplierLevels.clear(); while (aTok.hasMoreTokens()) { skillMultiplierLevels.add(aTok.nextToken()); } } /** * Set the base DC for spells. * @param arg */ public void setSpellBaseDC(final String arg) { spellBaseDC = arg; } /** * Get the base DC for Spells. * @return the base DC for Spells */ public String getSpellBaseDC() { return spellBaseDC; } /** * Set the base concentration bonus for spells. * @param arg */ public void setSpellBaseConcentration(final String arg) { spellBaseConcentration = arg; } /** * Get the base concentration bonus for Spells. * @return the base concentration bonus for Spells */ public String getSpellBaseConcentration() { return spellBaseConcentration; } /** * The formula used to compute spell ranges. * @param aString */ public void setSpellRangeFormula(final String aString) { final StringTokenizer aTok = new StringTokenizer(aString, "|", false); if (aTok.countTokens() < 2) { return; } final String aRange = aTok.nextToken().toUpperCase(); final String aFormula = aTok.nextToken(); spellRangeMap.put(aRange, aFormula); } /** * Returns the formula used for calculate the range of a spell. * @param aRange * @return spell range formula */ public String getSpellRangeFormula(final String aRange) { String aString = null; if (spellRangeMap != null) { aString = spellRangeMap.get(aRange); } return aString; } /** * Set the BAB Attack Bonus cycle. * @param arg */ public void setBabAttCyc(final int arg) { babAttCyc = arg; } /** * Get the BAB Attack Bonus cycle. * @return the BAB Attack Bonus cycle */ public int getBabAttCyc() { return babAttCyc; } /** * Set the maximum BAB attacks allowed. * @param arg */ public void setBabMaxAtt(final int arg) { babMaxAtt = arg; } /** * Get the max BAB attacks allowed. * @return the max BAB attacks allowed */ public int getBabMaxAtt() { return babMaxAtt; } /** * Set the max BAB level. * @param arg */ public void setBabMaxLvl(final int arg) { babMaxLvl = arg; } /** * Get the max BAB level. * @return the max BAB level */ public int getBabMaxLvl() { return babMaxLvl; } /** * Set a 2nd variable display name. * @param aString */ public void setVariableDisplay2Name(final String aString) { displayVariable2Name = aString; } /** * Set a 2nd variable display text. * @param aString */ public void setVariableDisplay2Text(final String aString) { displayVariable2Text = aString; } /** * Set a 3rd variable display name. * @param aString */ public void setVariableDisplay3Name(final String aString) { displayVariable3Name = aString; } /** * Set a 3rd variable display text. * @param aString */ public void setVariableDisplay3Text(final String aString) { displayVariable3Text = aString; } /** * Set a variable display name. * @param aString */ public void setVariableDisplayName(final String aString) { displayVariableName = aString; } /** * Set a 2nd variable display text. * @param aString */ public void setVariableDisplayText(final String aString) { displayVariableText = aString; } /** * Formula used to compute Wield Category steps. * @param aString */ public void setWCStepsFormula(final String aString) { wcStepsFormula = aString; } /** * Get the formula used to compute Wield Category steps. * @return formula used to compute Wield Category steps */ public String getWCStepsFormula() { return wcStepsFormula; } /** * Get the weapon categories. * @return the weapon categories */ public String getWeaponCategories() { return weaponCategories; } /** * Get the weapon types. * @return the weapon types */ public String getWeaponTypes() { return weaponTypes; } /** * Get the weapon reach formula. * @return String the weaopn reach formula * @deprecated due to EQREACH code control */ public String getWeaponReachFormula () { return this.weaponReachFormula; } /** * Get the XP awards. * @return the XP awards */ public Map<Integer, Integer> getXPAwards() { return xpAwardsMap; } /** * Get the CR steps for CRs lower than CR 1. * @return the CR steps */ public Map<Integer, String> getCRSteps() { return crStepsMap; } /** * Get the internal Integer representation for a CR. * @return the CR steps */ public Integer getCRInteger(String cr) { if (cr.startsWith("1/")) { for (Map.Entry<Integer, String> entry : crStepsMap.entrySet()) { if (entry.getValue().equals(cr)) { return entry.getKey(); } } return null; } return Integer.parseInt(cr); } /** * Get the CR steps for CRs lower than CR 1. * @return the CR steps */ public String getCRThreshold() { return crThreshold; } /** * Return true if the AC Type is Valid. * @param ACType * @return true if the AC Type is Valid */ @Deprecated public boolean isValidACType(final String ACType) { return ACTypeAddMap.containsListFor(ACType) || ACTypeRemoveMap.containsListFor(ACType); } /** * Appends to the ACTypeRemoveMap. * @param ACType * @param controls */ @Deprecated public void addACRemoves(final String ACType, Collection<ACControl> controls) { ACTypeRemoveMap.addAllToListFor(ACType, controls); } /** * Appends to the ACTypeAddMap. * @param ACType * @param controls */ @Deprecated public void addACAdds(final String ACType, Collection<ACControl> controls) { ACTypeAddMap.addAllToListFor(ACType, controls); } /** * Add Class Type. * * @param aString */ public void addClassType(final String aString) { if (Constants.LST_DOT_CLEAR.equals(aString)) { classTypeList = null; return; } if (classTypeList == null) { classTypeList = new ArrayList<>(); } final ClassType aClassType = new ClassType(); final StringTokenizer aTok = new StringTokenizer(aString, "\t"); aClassType.setName(aTok.nextToken().intern()); //Name of the Class Type while (aTok.hasMoreTokens()) { final String bString = aTok.nextToken(); if (bString.startsWith("CRFORMULA:")) { aClassType.setCRFormula(bString.substring(10)); } else if (bString.startsWith("CRMOD:")) { aClassType.setCRMod(bString.substring(6)); } else if (bString.startsWith("CRMODPRIORITY:")) { try { aClassType.setCRModPriority(new Integer(bString.substring(14))); } catch(NumberFormatException e) { Logging.errorPrint("Illegal value for miscinfo.CLASSTYPE.CRMODPRIORITY: " + bString.substring(14)); } } else if (bString.startsWith("XPPENALTY:")) { aClassType.setXPPenalty(bString.substring(10).equals("YES")); } else if (bString.startsWith("ISMONSTER:")) { aClassType.setMonster(bString.substring(10).equals("YES")); } else { Logging.errorPrint("Incorrect tag in miscinfo.CLASSTYPE: " + bString); } } classTypeList.add(aClassType); } /** * Add a data set to the list of Default Data Sets. * @param dataSetKey The key of the data set to add. */ public void addDefaultDataSet(final String dataSetKey) { if (defaultDataSetList == null) { defaultDataSetList = new ArrayList<>(); } defaultDataSetList.add(dataSetKey); } /** * Empty the list of Default Data Sets. */ public void clearDefaultDataSetList() { defaultDataSetList.clear(); } /** * Add a row to the Deity List. The list will be created if necessary. * The special value ".CLEAR" disposes of the list. * @param argDeityLine */ public void addDeityList(final String argDeityLine) { if (Constants.LST_DOT_CLEAR.equals(argDeityLine)) { defaultDeityList = null; return; } if (defaultDeityList == null) { defaultDeityList = new ArrayList<>(); } defaultDeityList.add(argDeityLine); } /** * Add Load String. * @param aString */ public void addLoadString(final String aString) { loadStrings.add(aString); } /** * Add Plus calculation. * @param aString */ public void addPlusCalculation(final String aString) { final int idx = aString.indexOf('|'); if (idx > 0) { if (plusCalcs == null) { plusCalcs = new HashMap<>(); } plusCalcs.put(aString.substring(0, idx).toUpperCase(), aString.substring(idx + 1)); } } /** * Add a Weapon Category. * @param aString */ public void addWeaponCategory(final String aString) { weaponCategories += ('|' + aString); } /** * Add a Weapon Type. * @param aString */ public void addWeaponType(final String aString) { weaponTypes += ('|' + aString); } /** * Wield Categories. * @param wCat */ public void addWieldCategory(final WieldCategory wCat) { getModeContext().getReferenceContext().importObject(wCat); } /** * Set the XP Awards. * @param aString */ public void setXPAwards(final String aString) { String sTmp = "";; StringTokenizer aTok = new StringTokenizer(aString, "|", false); while (aTok.hasMoreTokens()) { try { sTmp = aTok.nextToken(); final String xpAward[] = sTmp.split("="); xpAwardsMap.put(getCRInteger(xpAward[0]), new Integer(xpAward[1])); } catch (ArrayIndexOutOfBoundsException | NumberFormatException e) { Logging.errorPrint("Illegal value for miscinfo.XPAWARD: " + sTmp); } } } /** * Set the CR steps for CRs lower than CR 1. * @param aString */ public void setCRSteps(final String aString) { StringTokenizer aTok = new StringTokenizer(aString, "|", false); for (Integer index = 0; aTok.hasMoreTokens(); index--) { crStepsMap.put(index, aTok.nextToken()); } } /** * Set the CR key class threshold. * @param aString */ public void setCRThreshold(final String aString) { crThreshold = aString; } @Override public int compareTo(final Object obj) { if (obj != null) { final int iOrder = ((GameMode) obj).getDisplayOrder(); if (iOrder < displayOrder) { return 1; } else if (iOrder > displayOrder) { return -1; } // // Order matches, so put in alphabetical order // // should throw a ClassCastException for non-PObjects, // like the Comparable interface calls for return name.compareToIgnoreCase(((GameMode) obj).name); } return 1; } /** * Set the weapon reach forumla. * @param aString the new weapon reach formula * @deprecated due to EQREACH code control */ public void setWeaponReachFormula (String aString) { this.weaponReachFormula = aString; } /** * Set the acAbbrev field. */ String getACAbbrev() { return acAbbrev; } /** * Answer the information about AC. * @return AC text */ public String getACText() { return acName; } /** * Answer with the alignment. * @return alignment name */ String getAlignmentText() { return alignmentName; } /** * */ public List<String> getAllowedModes() { if (allowedModes == null) { final List<String> modes = new ArrayList<>(1); modes.add(name); return modes; } return allowedModes; } /** * */ String getAltHPAbbrev() { return althpAbbrev; } /** * Wound Points. * @return alt hp name */ String getAltHPText() { return althpName; } /** * Levels at which all characters get bonus feats. * @return List */ List<String> getBonusFeatLevels() { return bonusFeatLevels; } /** * Levels at which all characters get bonus to stats. * @return List */ List<String> getBonusStatLevels() { return bonusStatLevels; } /** * Currency abbreviation. * @return currency unit abbreviation */ @Override public String getCurrencyDisplay() { return currencyUnitAbbrev; } /** * Get Damage Resistance Text. * @return Get Damage Resistance Text */ public String getDamageResistanceText() { return damageResistance; } /** * Default spell book name. * @return default spell book */ String getDefaultSpellBook() { return defaultSpellBook; } /** * Default unit set. * @return default unit set */ String getDefaultUnitSet() { return defaultUnitSet; } /** * Answer the deity list. May be null. * @return default unit set */ List<String> getDeityList() { return defaultDeityList; } /** * Gets the list of default data sets. * * @return the default data set list */ @Override public List<String> getDefaultDataSetList() { return defaultDataSetList; } /** * Answer the preferred display order. * @return default unit set */ int getDisplayOrder() { return displayOrder; } /** * HP. * @return HP abbreviation */ String getHPAbbrev() { return hpAbbrev; } /** * */ String getHPText() { return hpName; } /** * */ List<String> getLoadStrings() { return loadStrings; } /** * Answer the unit of currency. * @return currency unit */ String getLongCurrencyDisplay() { return currencyUnit; } /** * */ public String getRankModFormula() { return rankModFormula; } boolean getShowClassDefense() { return showClassDefense; } List<String> getSkillMultiplierLevels() { return skillMultiplierLevels; } String getVariableDisplay2Name() { return displayVariable2Name; } String getVariableDisplay2Text() { return displayVariable2Text; } String getVariableDisplay3Name() { return displayVariable3Name; } String getVariableDisplay3Text() { return displayVariable3Text; } String getVariableDisplayName() { return displayVariableName; } /** * Variable Display. * @return variable display text */ String getVariableDisplayText() { return displayVariableText; } /** * Set the range increment penalty for ranged weapons. * * @param value * For penalties set this to be a negative number, for bonuses to * long range set this to be a positive number, for no range * penalty set this to be 0 */ public void setRangePenalty(int value) { rangePenalty = value; } /** * Get the range penalty. * @return range penalty */ public int getRangePenalty() { return rangePenalty; } /** * Set the cost for class skills * @param value */ public void setSkillCost_Class(int value) { skillCosts_Class = value; } /** * Set the cost for cross class skills. * @param value */ public void setSkillCost_CrossClass(int value) { skillCost_CrossClass = value; } /** * Set the cost for exclusive skills. * @param value */ public void setSkillCost_Exclusive(int value) { skillCost_Exclusive = value; } /** * Get the cost for class skills. * @return cost for class skills */ public int getSkillCost_Class() { return skillCosts_Class; } /** * Get the cost for cross class skills. * @return cost for cross class skills */ public int getSkillCost_CrossClass() { return skillCost_CrossClass; } /** * Get the cost for exclusive skills. * @return cost for exclusive skills */ public int getSkillCost_Exclusive() { return skillCost_Exclusive; } /** * Set the point pool name. * @param argPoolName */ public void setPointPoolName(final String argPoolName) { pointPoolName = argPoolName; } /** * Get the point pool name. * @return point pool name */ public String getPointPoolName() { return pointPoolName; } /** * Set the penalty for non proficiency. * @param argPenalty */ public void setNonProfPenalty(final int argPenalty) { nonProfPenalty = argPenalty; } /** * Get the penalty for non proficiency. * @return the penalty for non proficiency */ public int getNonProfPenalty() { return nonProfPenalty; } /** * Set the HP Formula. * @param argFormula */ public void setHPFormula(final String argFormula) { hpFormula = argFormula; } /** * Get the HP Formula. * @return HP Formula */ public String getHPFormula() { return hpFormula; } /** * Set Add with meta magic message. * @param argMsg */ public void setAddWithMetamagicMessage(final String argMsg) { addWithMetamagic = argMsg; } /** * Get add with meta magic message. * @return add with meta magic message */ @Override public String getAddWithMetamagicMessage() { return addWithMetamagic; } /** * Set square size. * @param argSize */ public void setSquareSize(final double argSize) { squareSize = argSize; } /** * Get square size. * @return square size */ public double getSquareSize() { return squareSize; } /** * Get the set unit. * @return the unti that is set */ public UnitSet getUnitSet() { return selectedUnitSet; } /** * Return true if the unit has been set. * @param unitSetName * @return true if the unit has been set */ public boolean selectUnitSet(final String unitSetName) { final UnitSet ui = getModeContext().getReferenceContext() .silentlyGetConstructedCDOMObject(UnitSet.class, unitSetName); if (ui == null) { return false; } selectedUnitSet = ui; return true; } /** * Return true if the default unit has been set. * @return true if the unit has been set */ public boolean selectDefaultUnitSet() { final UnitSet ui = getModeContext().getReferenceContext() .silentlyGetConstructedCDOMObject(UnitSet.class, defaultUnitSet); if (ui == null) { return false; } selectedUnitSet = ui; return true; } /** * Add a PointBuyCost object to purchase mode stat costs. * @param pbc */ public void addPointBuyStatCost(final PointBuyCost pbc) { if (pointBuyStatCosts == null) { // Sort NUMERICALLY, not alphabetically! // CONSIDER Huh? The natural order of Integer IS numerically... - thpr 10/20/06 pointBuyStatCosts = new TreeMap<>(new ComparableComparator<>()); } abilityScoreCost = null; pointBuyStatCosts.put(pbc.getStatValue(), pbc); } /** * Clear purchase mode stat costs. */ public void clearPointBuyStatCosts() { pointBuyStatCosts = null; abilityScoreCost = null; } /** * Get the point buy by stat mapping. * @return the point buy by stat mapping */ public SortedMap<Integer, PointBuyCost> getPointBuyStatCostMap() { return pointBuyStatCosts; } /** * Find a user-defined purchase method by name. * @param methodName * @return the purchase method or null */ public PointBuyMethod getPurchaseMethodByName(final String methodName) { return getModeContext().getReferenceContext().silentlyGetConstructedCDOMObject( PointBuyMethod.class, methodName); } /** * Set the purchase mode method name. * @param argMethodName */ public void setPurchaseMethodName(final String argMethodName) { if (!argMethodName.isEmpty()) { setRollMethod(Constants.CHARACTER_STAT_METHOD_PURCHASE); } purchaseMethodName = argMethodName; gamemodePrefsContext.setProperty("purchaseMethodName", argMethodName); //$NON-NLS-1$ } /** * Get the highest stat score that can be purchased free. * @param aPC * @return purchase mode base score */ public int getPurchaseModeBaseStatScore(final PlayerCharacter aPC) { int minVal = getPurchaseScoreMin(aPC); for (int i = 0, x = getPurchaseScoreMax() - getPurchaseScoreMin() + 1; i < x; ++i) { if (getAbilityScoreCost(i) == 0) { if ((getPurchaseScoreMin() + i) >= minVal) { return getPurchaseScoreMin() + i; } } } // // Make sure that the minimum stat value is legal. This could happen if there are no // stat values that are considered to be free. // if (getPurchaseScoreMin() == minVal) { minVal -= 1; if (minVal < statMin) { minVal = statMin; } } return minVal; } /** * Get the purchase mode method name. * @return the purchase mode method name */ public String getPurchaseModeMethodName() { if (!isPurchaseStatMode()) { return null; } return purchaseMethodName; } /** * Get the purchase mode method pool formula. * @return the purchase mode method pool formula */ public String getPurchaseModeMethodPoolFormula() { if (!isPurchaseStatMode()) { return "-1"; } return getPurchaseMethodByName(purchaseMethodName).getPointFormula(); } /** * Get the highest stat value in the purchase mode stat table. * @return purchase mode maximum */ public int getPurchaseScoreMax() { if (pointBuyStatCosts == null) { return -1; } return pointBuyStatCosts.lastKey(); } /** * Get the maximum score you can purchase. * @param pc * @return the maximum score you can purchase */ public int getPurchaseScoreMax(final PlayerCharacter pc) { if (pc == null) { return getPurchaseScoreMax(); } int lastStat = -1; if (pointBuyStatCosts != null) { for ( Integer statValue : pointBuyStatCosts.keySet() ) { final PointBuyCost pbc = pointBuyStatCosts.get(statValue); if (pbc.qualifies(pc, null)) { lastStat = statValue.intValue(); } } } return lastStat; } /** * Get the lowest stat value in the purchase mode stat table. * @return purchase score minimum */ public int getPurchaseScoreMin() { if (pointBuyStatCosts == null) { return -1; } return pointBuyStatCosts.firstKey(); } /** * Get the minimum score you can purchase. * @param pc * @return the minimum score you can purchase */ public int getPurchaseScoreMin(final PlayerCharacter pc) { if (pc == null) { return getPurchaseScoreMin(); } int lastStat = -1; if (pointBuyStatCosts != null) { for ( int statValue : pointBuyStatCosts.keySet() ) { final PointBuyCost pbc = pointBuyStatCosts.get(statValue); if (pbc.qualifies(pc, null)) { lastStat = statValue; break; } } } return lastStat; } /** * Returns true if we are in a stat purchase mode. * @return true if we are in a stat purchase mode */ public boolean isPurchaseStatMode() { // Can't have purchase mode if no costs specified if ((pointBuyStatCosts == null) || (pointBuyStatCosts.isEmpty()) || (getRollMethod() != Constants.CHARACTER_STAT_METHOD_PURCHASE) || (purchaseMethodName.isEmpty())) { return false; } return getPurchaseMethodByName(purchaseMethodName) != null; } /** * * @param argRollMethod */ public void setRollMethod(final int argRollMethod) { rollMethod = argRollMethod; gamemodePrefsContext.setInt("rollMethod", argRollMethod); //$NON-NLS-1$ if (argRollMethod != Constants.CHARACTER_STAT_METHOD_PURCHASE) { setPurchaseMethodName(""); //$NON-NLS-1$ } } /** * * @return roll method */ public int getRollMethod() { return rollMethod; } /** * Get the cost for an ability score. * @return the cost for an ability score */ public int[] getAbilityScoreCost() { if (!isPurchaseStatModeAllowed()) { //better to return a Zero length array than null. return null; } // Only build this list once if (abilityScoreCost != null) { return abilityScoreCost; } abilityScoreCost = new int[getPurchaseScoreMax() - getPurchaseScoreMin() + 1]; // Should be 1 value for each stat in range int i = 0; int lastStat = Integer.MIN_VALUE; int lastCost = 0; for ( int statValue : pointBuyStatCosts.keySet() ) { // Fill in any holes in the stat list by using the previous stat cost if ((lastStat != Integer.MIN_VALUE) && (lastStat + 1 != statValue)) { for (int x = lastStat + 1; x < statValue; ++x) { abilityScoreCost[i++] = lastCost; } } final int statCost = pointBuyStatCosts.get(statValue).getBuyCost(); lastStat = statValue; lastCost = statCost; abilityScoreCost[i++] = lastCost; } return abilityScoreCost; } /** * Get the cost for an ability score. * @param abilityScoreIndex * @return the cost for an ability score */ public int getAbilityScoreCost(final int abilityScoreIndex) { final int[] asc = getAbilityScoreCost(); if (asc == null) { return 0; } return asc[abilityScoreIndex]; } /** * Set the roll method expression by name. * @param aString */ public void setRollMethodExpressionByName(final String aString) { activeRollMethod = getModeContext().getReferenceContext().silentlyGetConstructedCDOMObject(RollMethod.class, aString); if (activeRollMethod == null) { setRollMethod(Constants.CHARACTER_STAT_METHOD_USER); } else { setRollMethod(Constants.CHARACTER_STAT_METHOD_ROLLED); } gamemodePrefsContext.setProperty("rollMethodExpression", aString); //$NON-NLS-1$ } /** * Get the cost for an ability score. * @return the cost for an ability score */ public String getRollMethodExpression() { if (activeRollMethod != null) { return activeRollMethod.getMethodRoll(); } return ""; } /** * Get roll method expression name. * @return roll method expression name */ public String getRollMethodExpressionName() { if (activeRollMethod != null) { return activeRollMethod.getDisplayName(); } return ""; } /** * Return true if the purchasing of stats mode is allowed. * @return true if the purchasing of stats mode is allowed */ public boolean isPurchaseStatModeAllowed() { if ((pointBuyStatCosts == null) || (pointBuyStatCosts.isEmpty())) { return false; } return true; } /** * Set the value for all stats. * @param argAllStatsValue */ public void setAllStatsValue(final int argAllStatsValue) { allStatsValue = argAllStatsValue; gamemodePrefsContext.setInt("allStatsValue", argAllStatsValue); //$NON-NLS-1$ } /** * Get the value of all stats. * @return the value of all stats */ public int getAllStatsValue() { return allStatsValue; } /** * Returns the currently set rolling method for character stats. * * @return RollMethod the current rolling method */ public RollMethod getCurrentRollingMethod() { return activeRollMethod; } /** * Set the minimum stat. * @param argMin */ public void setStatMin(final int argMin) { statMin = argMin; } /** * Get the minimum stat. * @return minimum stat */ public int getStatMin() { return statMin; } /** * Set the maximum stat. * @param argMax */ public void setStatMax(final int argMax) { statMax = argMax; } /** * Get the maximum stat. * @return maximum stat */ public int getStatMax() { return statMax; } /** * Return an <b>unmodifiable</b> version of the schools list. * @return an <b>unmodifiable</b> version of the schools list. */ public List<String> getUnmodifiableSchoolsList() { return Collections.unmodifiableList(schoolsList); } /** * Add the school to the list. * @param school */ public void addToSchoolList(final String school) { if (!schoolsList.contains(school)) { schoolsList.add(school); } } /** * Add the display text for a stat. * @param statValue * @param statText */ public void addStatDisplayText(final int statValue, final String statText) { if (statDisplayText == null) { // Sort NUMERICALLY, not alphabetically! // CONSIDER Huh? The natural order of Integer IS numerically... - thpr 10/20/06 statDisplayText = new TreeMap<>(new ComparableComparator<>()); } statDisplayText.put(statValue, statText); } /** * Get the display text of a stat. * @param statValue * @return the display text of a stat */ public String getStatDisplayText(final int statValue) { String statText; // // If no alternate text available, then display the number only // if (statDisplayText == null) { statText = Integer.toString(statValue); } else { statText = statDisplayText.get(statValue); if (statText == null) { final int firstKey = statDisplayText.firstKey(); if (statValue < firstKey) { statText = "???" + Integer.toString(statValue) + "???"; } else { final int lastKey = statDisplayText.lastKey(); statText = getStatDisplayText(lastKey) + statDisplayTextAppend + getStatDisplayText(statValue - lastKey); } } } return statText; } /** * Return true if the skill rank display text is there. * @return true if the skill rank display text is there */ public boolean hasSkillRankDisplayText() { return (skillRankDisplayText == null) ? false : true; } /** * Add display text for a skill rank. * @param rankValue * @param rankText */ public void addSkillRankDisplayText(final int rankValue, final String rankText) { if (skillRankDisplayText == null) { // Sort NUMERICALLY, not alphabetically! // CONSIDER Huh? The natural order of Integer IS numerically... - thpr 10/20/06 skillRankDisplayText = new TreeMap<>(new ComparableComparator<>()); } skillRankDisplayText.put(rankValue, rankText); } /** * Get display text for a skill rank. * @param rankValue * @return display text for a skill rank */ public String getSkillRankDisplayText(final int rankValue) { String rankText; // // If no alternate text available, then display the number only // if (skillRankDisplayText == null) { rankText = Integer.toString(rankValue); } else { rankText = skillRankDisplayText.get(rankValue); if (rankText == null) { final int firstKey = skillRankDisplayText.firstKey(); if (rankValue < firstKey) { rankText = "???" + Integer.toString(rankValue) + "???"; } else { final int lastKey = skillRankDisplayText.lastKey(); rankText = getSkillRankDisplayText(lastKey) + statDisplayTextAppend + getSkillRankDisplayText(rankValue - lastKey); } } } return rankText; } //BONUSSTACKLIST /** * Add an item to the bonus stacking list. * @param item */ public void addToBonusStackList(final String item) { if(!bonusStackList.contains(item)) { bonusStackList.add(item); } } /** * Clears the bonus stacking list. */ public void clearBonusStacksList() { bonusStackList.clear(); } /** * Return an <b>unmodifiable</b> version of the bonus stacking list. * @return an <b>unmodifiable</b> version of the bonus stacking list. */ public List<String> getUnmodifiableBonusStackList() { return Collections.unmodifiableList(bonusStackList); } /** * Gets the <tt>AbilityCategory</tt> for the given key. * * @param aKey The key of the <tt>AbilityCategory</tt> to retreive. * * @return The requested <tt>AbilityCategory</tt> or <tt>null</tt> if the * category is not found in this game mode. */ public AbilityCategory getAbilityCategory(final String aKey) { AbilityCategory ac = silentlyGetAbilityCategory(aKey); // Empty aKey indicates return null because // PreAbilityTester.buildAbilityList uses that as a global // (all Category) getch if (aKey == null || (ac == null && !aKey.isEmpty())) { Logging.errorPrint("Attempt to fetch AbilityCategory: " + aKey + "... but it does not exist"); } return ac; } /** * */ public AbilityCategory silentlyGetAbilityCategory(final String aKey) { AbilityCategory cat = getContext().getReferenceContext() .silentlyGetConstructedCDOMObject(AbilityCategory.class, aKey); if (cat != null) { return cat; } if (AbilityCategory.LANGBONUS.getKeyName().equals(aKey)) { return AbilityCategory.LANGBONUS; } return null; } /** * Returns a <tt>Collection</tt> of <tt>AbilityCategory</tt> objects defined * by this game mode. * * @return A <tt>Collection</tt> of <tt>AbilityCategory</tt> objects. */ public Collection<AbilityCategory> getAllAbilityCategories() { return getContext().getReferenceContext() .getConstructedCDOMObjects(AbilityCategory.class); } /** * Returns a <tt>Collection</tt> of <tt>AbilityCategory</tt> objects * defined by this game mode that match the category key. * * @param key The category key to filter for. * @return A <tt>Collection</tt> of <tt>AbilityCategory</tt> objects. */ public Collection<AbilityCategory> getAllAbilityCatsForKey(String key) { if (key == null) { return Collections.emptyList(); } List<AbilityCategory> catList = new ArrayList<>(); for (AbilityCategory cat : getAllAbilityCategories()) { if (key.equals(cat.getKeyName()) || key.equals(cat.getParentCategory().getKeyName())) { catList.add(cat); } } return Collections.unmodifiableCollection(catList); } /** * */ public void setPreviewDir(final String aDir) { thePreviewDir = aDir; } /** * */ public String getPreviewDir() { return thePreviewDir; } /** * */ public void setDefaultPreviewSheet(final String aSheet) { theDefaultPreviewSheet = aSheet; } /** * */ public String getDefaultPreviewSheet() { return theDefaultPreviewSheet; } /** * Parses the DIESIZE tag's values to create * the dieSizes array. * * @param value */ public void setDieSizes(final String value) { final StringTokenizer aTok = new StringTokenizer(value, ",", false); List<Integer> list = new ArrayList<>(); while (aTok.hasMoreTokens()) { String aString = aTok.nextToken(); // in case there is training\leading whitespace after the comma split aString = aString.trim(); String minValue; String maxValue; try { if (aString.contains("MIN=")) { String[] t = aString.split("MIN="); minValue = t[1]; int die = Integer.parseInt(minValue); setMinDieSize(die); list.add(die); } else if (aString.contains("MAX=")) { String[] t = aString.split("MAX="); maxValue = t[1]; int die = Integer.parseInt(maxValue); setMaxDieSize(die); list.add(die); } else { int die = Integer.parseInt(aString); list.add(die); } } catch (NumberFormatException e) { Logging.errorPrint("Invalid integer value for DIESIZES: " + aString + ". Original value: DIESIZES:"+ value); } } if (list.isEmpty()) { return; } int[] dieSizes = new int[list.size()]; for (int i = 0; i < list.size(); i++) { dieSizes[i] = list.get(i); } list = null; this.setDieSizes(dieSizes); } /** * Get's current gamemodes MaxDieSize. * @return maxDieSize */ public int getMaxDieSize() { return maxDieSize; } /** * Sets's current gamemodes MaxDieSize. * @param dice */ public void setMaxDieSize(final int dice) { maxDieSize = dice; } /** * Get's current gamemodes MinDieSize. * @return minDieSize */ public int getMinDieSize() { return minDieSize; } /** * Sets's current gamemodes MinDieSize. * @param dice */ public void setMinDieSize(final int dice) { minDieSize = dice; } /** * Get's current gamemodes DieSizes. * @return dieSizes array */ public int[] getDieSizes() { return dieSizes; } /** * Set's DieSizes available for the gamemode. * @param die The parsed integer diesizes */ public void setDieSizes(int[] die) { this.dieSizes = die; } /** * Retrieve the list of equipment types which flag it as able to * be resized by the automatic resize feature. * @return the resizableTypeList */ public List<String> getResizableTypeList() { return Collections.unmodifiableList(resizableTypeList); } /** * Set the list of equipment types which flag it as able to * be resized by the automatic resize feature. * * @param resizableTypeList the resizableTypeList to set */ public void setResizableTypeList(List<String> resizableTypeList) { this.resizableTypeList = resizableTypeList; } /** * Retrieve the list of character types (e.g. PC or NPC). * @return the characterTypeList */ public List<String> getCharacterTypeList() { return Collections.unmodifiableList(characterTypeList); } /** * Set the list of character types (e.g. PC or NPC). * * @param characterTypeList the characterTypeList to set */ public void setCharacterTypeList(List<String> characterTypeList) { this.characterTypeList = characterTypeList; } /** * Retrieve the list of monster roles. * @return the monsterRoleList */ public List<String> getMonsterRoleList() { return Collections.unmodifiableList(monsterRoleList); } /** * Set the list of known monster roles. * * @param monsterRoleList the monsterRoleList to set */ public void setMonsterRoleList(List<String> monsterRoleList) { this.monsterRoleList = monsterRoleList; } /** * Retrieve the default monster role. * @return the monsterRoleDefault */ public List<String> getMonsterRoleDefaultList() { return new ArrayList<>(Arrays.asList(monsterRoleDefault)); } /** * Set the list of known monster roles. * * @param monsterRoleDefault the monsterRoleDefault to set. */ public void setMonsterRoleDefault(String monsterRoleDefault) { this.monsterRoleDefault = monsterRoleDefault; } private ConsolidatedListCommitStrategy masterLCS = new ConsolidatedListCommitStrategy(); private LoadContext context = new RuntimeLoadContext(getRefContext(), masterLCS); private GameReferenceContext gameRefContext = new GameReferenceContext(); private LoadContext modeContext = new RuntimeLoadContext(gameRefContext, masterLCS); private String defaultSourceTitle; /** * */ public void clearLoadContext() { masterLCS = new ConsolidatedListCommitStrategy(); AbstractReferenceContext referenceContext = getRefContext(); resolveInto(referenceContext); context = new RuntimeLoadContext(referenceContext, masterLCS); } /** * Takes references and abbreviations that have been placed into the * LoadContext for this GameMode and copies those references and * abbreviations into the given ReferenceContext * * @param referenceContext * The Reference Context into which the references from this * GameMode should be copied. */ public void resolveInto(AbstractReferenceContext referenceContext) { for (ReferenceManufacturer<?> rm : gameRefContext.getAllManufacturers()) { resolveReferenceManufacturer(referenceContext, rm); } } private AbstractReferenceContext getRefContext() { if (SettingsHandler.inputUnconstructedMessages()) { return new TrackingReferenceContext(); } else { return new RuntimeReferenceContext(); } } /** * */ public static <T extends Loadable> void resolveReferenceManufacturer( AbstractReferenceContext rc, ReferenceManufacturer<T> rm) { Class<T> c = rm.getReferenceClass(); ReferenceManufacturer<T> mfg; if (Categorized.class.isAssignableFrom(c)) { TransparentCategorizedReferenceManufacturer tcrm = (TransparentCategorizedReferenceManufacturer) rm; String category = tcrm.getCDOMCategory(); Class catClass = tcrm.getCategoryClass(); mfg = rc.getManufacturer((Class) c, catClass, category); } else { mfg = rc.getManufacturer(c); } for (CDOMReference<T> ref : rm.getAllReferences()) { ((TransparentReference<T>) ref).resolve(mfg); } rm.injectConstructed(mfg); } /** * */ public LoadContext getContext() { return context; } /** * */ public LoadContext getModeContext() { return modeContext; } /** * */ public MasterListInterface getMasterLists() { return masterLCS; } /** * */ public void addHiddenType(Class<?> cl, String s) { Set<String> set = hiddenTypes.get(cl); if (set == null) { set = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); hiddenTypes.put(cl, set); } set.add(s); } /** * Gets the name of the currently selected default XP table. * * @return the XP table name */ public String getDefaultXPTableName() { if (defaultXPTableName == null || defaultXPTableName.equals("") || !xpTableNames.contains(defaultXPTableName)) { if (xpTableNames.isEmpty()) { xpTableNames.add("Default"); } defaultXPTableName = xpTableNames.get(0); } return defaultXPTableName; } /** * Sets the default experience table by name. * * @param xpTableName the new XP table name */ public void setDefaultXPTableName(String xpTableName) { defaultXPTableName = xpTableName; } /** * Gets a list of names of all defined XP tables. * * @return the list of XP table names */ public List<String> getXPTableNames() { return xpTableNames; } /** * Add a name for an XP tables. * * @param xpTableName the new XP table name */ public void addXPTableName(String xpTableName) { xpTableNames.add(xpTableName); } /** * Gets the name of the currently selected default character type. * * @return the character type */ public String getDefaultCharacterType() { if (defaultCharacterType == null || defaultCharacterType.equals("") || !characterTypeList.contains(defaultCharacterType)) { if (characterTypeList.isEmpty()) { characterTypeList.add("Default"); } defaultCharacterType = characterTypeList.get(0); } return defaultCharacterType; } /** * Sets the default character type. * * @param characterType the new character type */ public void setDefaultCharacterType(String characterType) { defaultCharacterType = characterType; } /** * Checks if bonus stat stacking is allowed. * * @return true, if is bonus stat stacking allowed */ public boolean isBonusStatAllowsStack() { return bonusStatAllowsStack; } /** * Sets the bonus stat stacking allowed value. * * @param bonusStatAllowsStack the new bonus stat allows stack */ public void setBonusStatAllowsStack(boolean bonusStatAllowsStack) { this.bonusStatAllowsStack = bonusStatAllowsStack; } /** * * @return the bioSet */ public BioSet getBioSet() { return bioSet; } /** * * @param bioSet the bioSet to set */ public void setBioSet(BioSet bioSet) { this.bioSet = bioSet; } @Override public String toString() { return name; } /** * Sets the title of the default source (used on the quick sources dialog). * * @param title the new title */ public void setDefaultSourceTitle(String title) { this.defaultSourceTitle = title; } /** * Gets the default source title. * * @return the default source title */ @Override public String getDefaultSourceTitle() { return defaultSourceTitle; } /** * */ public String getTabName(Tab tab) { TabInfo ti = getContext().getReferenceContext().silentlyGetConstructedCDOMObject( TabInfo.class, tab.toString()); return ti.getResolvedName(); } /** * */ public boolean getTabShown(Tab tab) { TabInfo ti = getContext().getReferenceContext().silentlyGetConstructedCDOMObject( TabInfo.class, tab.toString()); return ti.isVisible(); } /** * */ public void setTabVisible(CDOMSingleRef<TabInfo> ref, Boolean set) { if (visibleTabs == null) { visibleTabs = new HashMap<>(); } visibleTabs.put(ref, set); } /** * */ public Boolean getTabVisibility(TabInfo ti) { if (visibleTabs == null) { return null; } for (Map.Entry<CDOMSingleRef<TabInfo>, Boolean> me : visibleTabs.entrySet()) { if (ti.equals(me.getKey().get())) { return me.getValue(); } } return null; } /* * End SHOWTAB compatibility */ /** * */ public LoadInfo getLoadInfo() { return getModeContext().getReferenceContext().silentlyGetConstructedCDOMObject( LoadInfo.class, getName()); } /** * * @return the file name of the InfoSheet relative to the base pcgen directory */ @Override public String getInfoSheet() { return theInfoSheet; } /** * * @param theInfoSheet the file name of the InfoSheet relative to the base pcgen directory */ public void setInfoSheet(String theInfoSheet) { this.theInfoSheet = theInfoSheet; } /** * * @return the file name of the skill InfoSheet relative to the base pcgen directory */ @Override public String getInfoSheetSkill() { return theInfoSheetSkill; } /** * * @param theInfoSheetSkill the file name of the skill InfoSheet relative to the base pcgen directory */ public void setInfoSheetSkill(String theInfoSheetSkill) { this.theInfoSheetSkill = theInfoSheetSkill; } /** * * @param theOutputSheetDirectory the directory for output sheets for the current game mode */ public void setOutputSheetDirectory(String theOutputSheetDirectory) { this.outputSheetDirectory = theOutputSheetDirectory; } /** * * @return the directory for output sheets for the current game mode */ @Override public String getOutputSheetDirectory() { return outputSheetDirectory; } /** * * @param sheet the file name of the InfoSheet relative to the base pcgen directory */ public void setOutputSheetDefault(String type, String sheet) { this.outputSheetDefaultMap.put(type, sheet); } /** * * @return the directory for output sheets for the current game mode */ @Override public String getOutputSheetDefault(String type) { return outputSheetDefaultMap.get(type); } /** * Register an icon to be used for equipment of the listed type. * @param equipType The equipment type * @param iconPath The path relative to the pcgen folder of the icon. * @param priority The importance of this icon, higher means more important */ public void setEquipTypeIcon(String equipType, String iconPath, int priority) { this.equipTypeIconMap.put(equipType.toUpperCase(), iconPath); this.equipTypeIconPriorityMap.put(equipType.toUpperCase(), priority); } /** * Retrieve the default icon to be used for equipment of the listed type. * @param equipType The equipment type * @return The path relative to the pcgen folder of the icon, null if none exists. */ public String getEquipTypeIcon(String equipType) { return this.equipTypeIconMap.get(equipType.toUpperCase()); } /** * Retrieve the priority of the listed type;s icon. A higher number means a higher * priority, generally the highest priority icon will be used. * @param equipType The equipment type * @return The priority, or 0 if none is known. */ public int getEquipTypeIconPriority(String equipType) { Integer priority = this.equipTypeIconPriorityMap.get(equipType.toUpperCase()); return priority == null ? 0 : priority; } @Override public String getCharSheetDir() { return getPreviewDir(); } @Override public String getDefaultCharSheet() { return getDefaultPreviewSheet(); } @Override public String getHeightUnit() { if ("ftin".equals(getUnitSet().getHeightUnit())) { return "inches"; } else { return getUnitSet().getHeightUnit(); } } @Override public String getWeightUnit() { return getUnitSet().getWeightUnit(); } /** * */ public AbilityCategory getFeatTemplate() { return featTemplate; } /** * */ public void setFeatTemplate(AbilityCategory featTemplate) { this.featTemplate = featTemplate; } public void setMaxNonEpicLevel(int i) { maxNonEpicLevel = i; } public int getMaxNonEpicLevel() { return maxNonEpicLevel; } }