From: <th...@us...> - 2008-11-25 02:54:36
|
Revision: 8488 http://pcgen.svn.sourceforge.net/pcgen/?rev=8488&view=rev Author: thpr Date: 2008-11-25 02:54:29 +0000 (Tue, 25 Nov 2008) Log Message: ----------- Global SPELLLEVEL token rebuild Modified Paths: -------------- Trunk/pcgen/code/src/java/pcgen/cdom/base/CDOMList.java Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/AssociationKey.java Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/AssociationListKey.java Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/MapKey.java Trunk/pcgen/code/src/java/pcgen/cdom/inst/PCClassLevel.java Trunk/pcgen/code/src/java/pcgen/core/Domain.java Trunk/pcgen/code/src/java/pcgen/core/Globals.java Trunk/pcgen/code/src/java/pcgen/core/PCClass.java Trunk/pcgen/code/src/java/pcgen/core/PObject.java Trunk/pcgen/code/src/java/pcgen/core/PlayerCharacter.java Trunk/pcgen/code/src/java/pcgen/core/analysis/DomainApplication.java Trunk/pcgen/code/src/java/pcgen/core/analysis/SpellLevel.java Trunk/pcgen/code/src/java/pcgen/core/chooser/SpellsChoiceManager.java Trunk/pcgen/code/src/java/pcgen/core/kit/KitSpells.java Trunk/pcgen/code/src/java/pcgen/core/npcgen/ClassData.java Trunk/pcgen/code/src/java/pcgen/core/npcgen/ClassDataParser.java Trunk/pcgen/code/src/java/pcgen/core/npcgen/Configuration.java Trunk/pcgen/code/src/java/pcgen/core/npcgen/NPCGenerator.java Trunk/pcgen/code/src/java/pcgen/core/term/PCMaxCastableClassTermEvaluator.java Trunk/pcgen/code/src/java/pcgen/gui/ChooseSpellDialog.java Trunk/pcgen/code/src/java/pcgen/gui/editor/EditorMainForm.java Trunk/pcgen/code/src/java/pcgen/gui/sources/SourceSelectionDialog.java Trunk/pcgen/code/src/java/pcgen/gui/tabs/spells/InfoSpellsSubTab.java Trunk/pcgen/code/src/java/pcgen/gui/tabs/spells/SpellModel.java Trunk/pcgen/code/src/java/pcgen/gui/utils/PObjectNode.java Trunk/pcgen/code/src/java/pcgen/io/PCGVer0Parser.java Trunk/pcgen/code/src/java/pcgen/io/PCGVer2Creator.java Trunk/pcgen/code/src/java/pcgen/io/PCGVer2Parser.java Trunk/pcgen/code/src/java/pcgen/rules/context/AbstractReferenceContext.java Trunk/pcgen/code/src/java/pcgen/rules/context/ConsolidatedListCommitStrategy.java Trunk/pcgen/code/src/java/plugin/exporttokens/SpellMemToken.java Trunk/pcgen/code/src/java/plugin/lsttokens/SpelllevelLst.java Trunk/pcgen/code/src/java/plugin/lsttokens/campaign/InfotextToken.java Trunk/pcgen/code/src/java/plugin/pretokens/test/PreSpellTester.java Trunk/pcgen/code/src/test/pcgen/core/term/EvaluatorFactoryTest.java Trunk/pcgen/code/src/test/pcgen/io/exporttoken/SpellMemTokenTest.java Trunk/pcgen/code/src/test/plugin/exporttokens/SpellListTokenTest.java Trunk/pcgen/code/testsuite/csheets/Quasvin.xml Removed Paths: ------------- Trunk/pcgen/code/src/java/pcgen/core/SpellSupport.java Trunk/pcgen/code/src/java/pcgen/core/spell/PCSpellTracker.java Modified: Trunk/pcgen/code/src/java/pcgen/cdom/base/CDOMList.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/cdom/base/CDOMList.java 2008-11-25 00:44:15 UTC (rev 8487) +++ Trunk/pcgen/code/src/java/pcgen/cdom/base/CDOMList.java 2008-11-25 02:54:29 UTC (rev 8488) @@ -38,4 +38,6 @@ * @return the Class of Object this CDOMList will identify */ public Class<T> getListClass(); + + public String getKeyName(); } Modified: Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/AssociationKey.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/AssociationKey.java 2008-11-25 00:44:15 UTC (rev 8487) +++ Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/AssociationKey.java 2008-11-25 02:54:29 UTC (rev 8488) @@ -71,8 +71,6 @@ public static final AssociationKey<Integer> OUTPUT_INDEX = new AssociationKey<Integer>(); - public static final AssociationKey<String> SPELL_KEY_CACHE = new AssociationKey<String>(); - public static final AssociationKey<String> CASTER_LEVEL = new AssociationKey<String>(); public static final AssociationKey<Formula> TIMES_PER_UNIT = new AssociationKey<Formula>(); Modified: Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/AssociationListKey.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/AssociationListKey.java 2008-11-25 00:44:15 UTC (rev 8487) +++ Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/AssociationListKey.java 2008-11-25 02:54:29 UTC (rev 8488) @@ -30,6 +30,7 @@ import pcgen.base.util.CaseInsensitiveMap; import pcgen.base.util.FixedStringList; import pcgen.base.util.NamedValue; +import pcgen.cdom.base.CDOMList; import pcgen.cdom.base.CDOMListObject; import pcgen.cdom.helper.ProfProvider; import pcgen.cdom.list.ClassSkillList; @@ -95,6 +96,8 @@ public static final AssociationListKey<Ability> ADDED_FEAT = new AssociationListKey<Ability>(); + public static final AssociationListKey<CDOMList<Spell>> SPELL_LIST_CACHE = new AssociationListKey<CDOMList<Spell>>(); + public static final AssociationListKey<CharacterSpell> CHARACTER_SPELLS = new AssociationListKey<CharacterSpell>(); Modified: Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/MapKey.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/MapKey.java 2008-11-25 00:44:15 UTC (rev 8487) +++ Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/MapKey.java 2008-11-25 02:54:29 UTC (rev 8488) @@ -22,7 +22,10 @@ */ package pcgen.cdom.enumeration; +import pcgen.base.util.HashMapToList; +import pcgen.cdom.base.CDOMList; import pcgen.cdom.helper.Aspect; +import pcgen.core.spell.Spell; /** * This is a Typesafe enumeration of legal Map Characteristics of an object. It @@ -49,6 +52,8 @@ public static final MapKey<AspectName, Aspect> ASPECT = new MapKey<AspectName, Aspect>(); /** TEST - a test map key. May be deleted and its usage replaced when a second Map Key is created. */ public static final MapKey<String, String> TEST = new MapKey<String, String>(); + public static final MapKey<Spell, HashMapToList<CDOMList<Spell>, Integer>> SPELL_MASTER_INFO = new MapKey<Spell, HashMapToList<CDOMList<Spell>, Integer>>(); + public static final MapKey<Spell, HashMapToList<CDOMList<Spell>, Integer>> SPELL_PC_INFO = new MapKey<Spell, HashMapToList<CDOMList<Spell>, Integer>>(); /** * Private constructor to prevent instantiation of this class. Modified: Trunk/pcgen/code/src/java/pcgen/cdom/inst/PCClassLevel.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/cdom/inst/PCClassLevel.java 2008-11-25 00:44:15 UTC (rev 8487) +++ Trunk/pcgen/code/src/java/pcgen/cdom/inst/PCClassLevel.java 2008-11-25 02:54:29 UTC (rev 8488) @@ -20,7 +20,6 @@ import java.util.List; import pcgen.cdom.base.CDOMObject; -import pcgen.cdom.base.Constants; import pcgen.cdom.enumeration.IntegerKey; import pcgen.cdom.enumeration.ListKey; import pcgen.cdom.enumeration.ObjectKey; Modified: Trunk/pcgen/code/src/java/pcgen/core/Domain.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/core/Domain.java 2008-11-25 00:44:15 UTC (rev 8487) +++ Trunk/pcgen/code/src/java/pcgen/core/Domain.java 2008-11-25 02:54:29 UTC (rev 8488) @@ -25,7 +25,13 @@ */ package pcgen.core; +import java.util.Collections; +import java.util.List; + +import pcgen.cdom.base.CDOMList; import pcgen.cdom.base.Constants; +import pcgen.cdom.enumeration.ObjectKey; +import pcgen.core.spell.Spell; import pcgen.core.utils.MessageType; import pcgen.core.utils.ShowMessageDelegate; @@ -38,12 +44,6 @@ public final class Domain extends PObject { @Override - public String getSpellKey(PlayerCharacter pc) - { - return "DOMAIN|" + getKeyName(); - } - - @Override public Domain clone() { Domain aObj = null; @@ -97,4 +97,16 @@ return result; } + + @Override + public List<? extends CDOMList<Spell>> getSpellLists(PlayerCharacter pc) + { + return Collections.singletonList(get(ObjectKey.DOMAIN_SPELLLIST)); + } + + @Override + public String getVariableSource() + { + return "DOMAIN|" + this.getKeyName(); + } } Modified: Trunk/pcgen/code/src/java/pcgen/core/Globals.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/core/Globals.java 2008-11-25 00:44:15 UTC (rev 8487) +++ Trunk/pcgen/code/src/java/pcgen/core/Globals.java 2008-11-25 02:54:29 UTC (rev 8488) @@ -50,6 +50,7 @@ import javax.swing.JFrame; +import pcgen.cdom.base.CDOMList; import pcgen.cdom.base.CDOMObject; import pcgen.cdom.base.CDOMObjectUtilities; import pcgen.cdom.base.Constants; @@ -1538,39 +1539,9 @@ * at least one of classKey and domainKey must not be "" * @return a List of Spell */ - public static List<Spell> getSpellsIn(final int level, final String classKey, final String domainKey) + public static List<Spell> getSpellsIn(final int level, List<? extends CDOMList<Spell>> spellLists) { final List<Spell> aList = new ArrayList<Spell>(); - final StringBuffer aBuf = new StringBuffer(); - - if (classKey.length() > 0) - { - if (classKey.indexOf('|') < 0) - { - aBuf.append("CLASS|").append(classKey); - } - else - { - aBuf.append(classKey); - } - } - - if (domainKey.length() > 0) - { - if (aBuf.length() > 0) - { - aBuf.append('|'); - } - - if (domainKey.indexOf('|') < 0) - { - aBuf.append("DOMAIN|").append(domainKey); - } - else - { - aBuf.append(domainKey); - } - } for (String aKey : spellMap.keySet()) { final Object obj = spellMap.get(aKey); @@ -1579,7 +1550,7 @@ { for (Spell aSpell : (ArrayList<Spell>)obj) { - if (SpellLevel.levelForKeyContains(aSpell, aBuf.toString(), level, currentPC)) + if (SpellLevel.levelForKeyContains(aSpell, spellLists, level, currentPC)) { aList.add(aSpell); } @@ -1589,7 +1560,7 @@ { final Spell aSpell = (Spell) obj; - if (SpellLevel.levelForKeyContains(aSpell, aBuf.toString(), level, currentPC)) + if (SpellLevel.levelForKeyContains(aSpell, spellLists, level, currentPC)) { aList.add(aSpell); } Modified: Trunk/pcgen/code/src/java/pcgen/core/PCClass.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/core/PCClass.java 2008-11-25 00:44:15 UTC (rev 8487) +++ Trunk/pcgen/code/src/java/pcgen/core/PCClass.java 2008-11-25 02:54:29 UTC (rev 8488) @@ -39,6 +39,7 @@ import pcgen.base.formula.Formula; import pcgen.base.lang.StringUtil; import pcgen.cdom.base.AssociatedPrereqObject; +import pcgen.cdom.base.CDOMList; import pcgen.cdom.base.CDOMListObject; import pcgen.cdom.base.CDOMObject; import pcgen.cdom.base.CDOMReference; @@ -64,8 +65,8 @@ import pcgen.cdom.helper.ShieldProfProvider; import pcgen.cdom.inst.PCClassLevel; import pcgen.cdom.list.ClassSkillList; +import pcgen.cdom.list.ClassSpellList; import pcgen.cdom.list.DomainList; -import pcgen.cdom.list.DomainSpellList; import pcgen.cdom.reference.CDOMDirectSingleRef; import pcgen.cdom.reference.CDOMSingleRef; import pcgen.core.analysis.DomainApplication; @@ -517,10 +518,9 @@ if (cd.isFromPCClass(getKeyName()) && (cd.getDomain() != null)) { - bList = - Globals.getSpellsIn(ix, - Constants.EMPTY_STRING, cd - .getDomain().getKeyName()); + bList = Globals.getSpellsIn(ix, Collections + .singletonList(cd.getDomain().get( + ObjectKey.DOMAIN_SPELLLIST))); } } } @@ -846,64 +846,6 @@ } /* - * PCCLASSLEVELONLY This is only part of the level, as the class spell list is - * calculated based on other factors, it is not a Tag - */ - @Override - public String getSpellKey(PlayerCharacter pc) - { - String stableSpellKey = pc.getAssoc(this, AssociationKey.SPELL_KEY_CACHE); - if (stableSpellKey != null) - { - return stableSpellKey; - } - - List<CDOMListObject<Spell>> classSpellList = pc.getAssocList(this, - AssociationListKey.CLASSSPELLLIST); - if (classSpellList == null) - { - chooseClassSpellList(pc); - - classSpellList = pc.getAssocList(this, - AssociationListKey.CLASSSPELLLIST); - - if (classSpellList == null) - { - stableSpellKey = "CLASS" + Constants.PIPE + getKeyName(); - - return stableSpellKey; - } - } - - final StringBuffer aBuf = new StringBuffer(); - boolean needPipe = false; - - for (CDOMListObject<Spell> keyStr : classSpellList) - { - if (needPipe) - { - aBuf.append(Constants.PIPE); - } - needPipe = true; - - if (DomainSpellList.class.equals(keyStr.getClass())) - { - aBuf.append("DOMAIN").append(Constants.PIPE).append( - keyStr.getLSTformat()); - } - else - { - aBuf.append("CLASS").append(Constants.PIPE).append( - keyStr.getLSTformat()); - } - } - - stableSpellKey = aBuf.toString(); - - return stableSpellKey; - } - - /* * FINALPCCLASSANDLEVEL This is required in PCClassLevel and should be present in * PCClass for PCClassLevel creation (in the factory) */ @@ -1260,8 +1202,8 @@ } } - pc.removeAssoc(this, AssociationKey.SPELL_KEY_CACHE); - getSpellKey(pc); + pc.removeAllAssocs(this, AssociationListKey.SPELL_LIST_CACHE); + getSpellLists(pc); } /* @@ -1432,13 +1374,14 @@ if (!aPC.isImporting()) { aPC.calcActiveBonuses(); - aPC.getSpellTracker().buildSpellLevelMap(newLevel); + //Need to do this again if caching is re-integrated + //aPC.getSpellTracker().buildSpellLevelMap(newLevel); } if ((level == 1) && !aPC.isImporting() && (curLevel == 0)) { checkForSubClass(aPC); - getSpellKey(aPC); + getSpellLists(aPC); } if (!aPC.isImporting() && (curLevel < level)) @@ -1512,8 +1455,6 @@ */ protected void removeKnownSpellsForClassLevel(final PlayerCharacter aPC) { - final String spellKey = getSpellKey(aPC); - if (!containsListFor(ListKey.KNOWN_SPELLS) || aPC.isImporting() || !aPC.getAutoSpells()) { @@ -1525,6 +1466,8 @@ return; } + List<? extends CDOMList<Spell>> lists = getSpellLists(aPC); + for (Iterator<CharacterSpell> iter = aPC.getSafeAssocList(this, AssociationListKey.CHARACTER_SPELLS) .iterator(); iter.hasNext();) @@ -1534,7 +1477,7 @@ final Spell aSpell = charSpell.getSpell(); // Check that the character can still cast spells of this level. - final Integer[] spellLevels = SpellLevel.levelForKey(aSpell, spellKey, aPC); + final Integer[] spellLevels = SpellLevel.levelForKey(aSpell, lists, aPC); for (Integer i = 0; i < spellLevels.length; i++) { final int spellLevel = spellLevels[i]; @@ -1571,8 +1514,7 @@ { // Get every spell that can be cast by this class. final List<Spell> cspelllist = - Globals.getSpellsIn(-1, getSpellKey(aPC), - Constants.EMPTY_STRING); + Globals.getSpellsIn(-1, getSpellLists(aPC)); if (cspelllist.isEmpty()) { return; @@ -1586,13 +1528,13 @@ final int _maxLevel = getMaxCastLevel(); // Get the key for this class (i.e. "CLASS|Cleric") - final String spellKey = getSpellKey(aPC); + List<? extends CDOMList<Spell>> lists = getSpellLists(aPC); // For every spell that this class can ever cast. for (Spell spell : cspelllist) { // For each spell level that this class can cast this spell at - final Integer[] spellLevels = SpellLevel.levelForKey(spell, spellKey, aPC); + final Integer[] spellLevels = SpellLevel.levelForKey(spell, lists, aPC); for (Integer si = 0; si < spellLevels.length; ++si) { final int spellLevel = spellLevels[si]; @@ -1726,12 +1668,13 @@ final StringBuffer pccTxt = new StringBuffer(200); pccTxt.append("CLASS:").append(getDisplayName()); pccTxt.append(super.getPCCText(false)); + pccTxt.append("\t"); + pccTxt.append(StringUtil.joinToStringBuffer(Globals.getContext().unparse( + this), "\t")); // now all the level-based stuff final String lineSep = System.getProperty("line.separator"); - pccTxt.append(StringUtil.joinToStringBuffer(Globals.getContext().unparse( - this), "\t")); for (Map.Entry<Integer, PCClassLevel> me : levelMap.entrySet()) { pccTxt.append(lineSep).append(me.getKey()).append('\t'); @@ -1809,7 +1752,7 @@ public void addClassSpellList(CDOMListObject<Spell> list, PlayerCharacter pc) { pc.addAssoc(this, AssociationListKey.CLASSSPELLLIST, list); - pc.removeAssoc(this, AssociationKey.SPELL_KEY_CACHE); + pc.removeAllAssocs(this, AssociationListKey.SPELL_LIST_CACHE); } /* @@ -4547,4 +4490,44 @@ pcl.ownBonuses(); } } + + @Override + public List<? extends CDOMList<Spell>> getSpellLists(PlayerCharacter pc) + { + List<CDOMList<Spell>> stableSpellList = pc.getAssocList(this, + AssociationListKey.SPELL_LIST_CACHE); + if (stableSpellList != null) + { + return stableSpellList; + } + + List<CDOMListObject<Spell>> classSpellList = pc.getAssocList(this, + AssociationListKey.CLASSSPELLLIST); + if (classSpellList == null) + { + chooseClassSpellList(pc); + + classSpellList = pc.getAssocList(this, + AssociationListKey.CLASSSPELLLIST); + + if (classSpellList == null) + { + ClassSpellList defaultList = get(ObjectKey.CLASS_SPELLLIST); + pc.addAssoc(this, AssociationListKey.SPELL_LIST_CACHE, defaultList); + return Collections.singletonList(defaultList); + } + } + + for (CDOMListObject<Spell> keyStr : classSpellList) + { + pc.addAssoc(this, AssociationListKey.SPELL_LIST_CACHE, keyStr); + } + return classSpellList; + } + + @Override + public String getVariableSource() + { + return "CLASS|" + this.getKeyName(); + } } Modified: Trunk/pcgen/code/src/java/pcgen/core/PObject.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/core/PObject.java 2008-11-25 00:44:15 UTC (rev 8487) +++ Trunk/pcgen/code/src/java/pcgen/core/PObject.java 2008-11-25 02:54:29 UTC (rev 8488) @@ -29,6 +29,7 @@ import java.net.URI; import java.text.ParseException; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashSet; @@ -38,8 +39,11 @@ import java.util.StringTokenizer; import pcgen.base.lang.StringUtil; +import pcgen.cdom.base.CDOMList; import pcgen.cdom.base.CDOMObject; +import pcgen.cdom.base.CDOMReference; import pcgen.cdom.base.Constants; +import pcgen.cdom.base.PrereqObject; import pcgen.cdom.base.TransitionChoice; import pcgen.cdom.enumeration.AssociationListKey; import pcgen.cdom.enumeration.ListKey; @@ -47,6 +51,8 @@ import pcgen.cdom.enumeration.Region; import pcgen.cdom.enumeration.StringKey; import pcgen.cdom.inst.PCClassLevel; +import pcgen.cdom.list.ClassSpellList; +import pcgen.cdom.list.DomainSpellList; import pcgen.core.bonus.BonusObj; import pcgen.core.bonus.BonusUtilities; import pcgen.core.chooser.ChooserUtilities; @@ -54,6 +60,7 @@ import pcgen.core.pclevelinfo.PCLevelInfo; import pcgen.core.prereq.PrereqHandler; import pcgen.core.prereq.Prerequisite; +import pcgen.core.spell.Spell; import pcgen.core.utils.KeyedListContainer; import pcgen.persistence.PersistenceLayerException; import pcgen.persistence.lst.output.prereq.PrerequisiteWriter; @@ -87,8 +94,6 @@ /** The name to display to the user. This should be internationalized. */ protected String displayName = Constants.EMPTY_STRING; - private SpellSupport spellSupport = new SpellSupport(); - private boolean isNewItem = true; private URI sourceURI = null; @@ -191,7 +196,6 @@ retVal.setName(displayName); retVal.put(StringKey.KEY_NAME, get(StringKey.KEY_NAME)); - retVal.spellSupport = spellSupport.clone(); // added 04 Aug 2003 by sage_sam -- bug#765749 // need to copy map correctly during a clone @@ -428,16 +432,6 @@ } /** - * Returns a hardcoded "POBJECT|" + name of this object - * @param pc TODO - * @return "POBJECT|" + name of this object - */ - public String getSpellKey(PlayerCharacter pc) - { - return "POBJECT|" + getKeyName(); //$NON-NLS-1$ - } - - /** * Get the user defined type by index * @param i * @return the user defined type by index @@ -847,8 +841,6 @@ txt.append(getDisplayName()); } - txt.append("\tKEY:").append(getKeyName()); - aString = getChoiceString(); if ((aString != null) && (aString.length() != 0)) @@ -887,9 +879,6 @@ txt.append("\tSOURCEPAGE:").append(aString); } - // SPELLLEVEL - txt.append('\t').append(getSpellSupport().getPCCText()); - return txt.toString(); } @@ -1158,15 +1147,6 @@ } /** - * Get the Spell Support for this object - * @return SpellSupport - */ - public SpellSupport getSpellSupport() - { - return spellSupport; - } - - /** * Get the list of bonuses for this object * @param as TODO * @return the list of bonuses for this object @@ -1551,4 +1531,26 @@ } } + public List<? extends CDOMList<Spell>> getSpellLists(PlayerCharacter pc) + { + return null; + } + + public String getVariableSource() + { + return "POBJECT|" + this.getKeyName(); + } + + public void clearSpellListInfo() + { + Collection<CDOMReference<? extends CDOMList<? extends PrereqObject>>> modLists = getModifiedLists(); + for (CDOMReference<? extends CDOMList<? extends PrereqObject>> ref : modLists) + { + if (ref.getReferenceClass().equals(ClassSpellList.class) + || ref.getReferenceClass().equals(DomainSpellList.class)) + { + removeAllFromList(ref); + } + } + } } Modified: Trunk/pcgen/code/src/java/pcgen/core/PlayerCharacter.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/core/PlayerCharacter.java 2008-11-25 00:44:15 UTC (rev 8487) +++ Trunk/pcgen/code/src/java/pcgen/core/PlayerCharacter.java 2008-11-25 02:54:29 UTC (rev 8488) @@ -60,6 +60,7 @@ import pcgen.base.util.NamedValue; import pcgen.base.util.WrappedMapSet; import pcgen.cdom.base.AssociatedPrereqObject; +import pcgen.cdom.base.CDOMList; import pcgen.cdom.base.CDOMObject; import pcgen.cdom.base.CDOMObjectUtilities; import pcgen.cdom.base.CDOMReference; @@ -76,6 +77,7 @@ import pcgen.cdom.enumeration.Gender; import pcgen.cdom.enumeration.IntegerKey; import pcgen.cdom.enumeration.ListKey; +import pcgen.cdom.enumeration.MapKey; import pcgen.cdom.enumeration.ObjectKey; import pcgen.cdom.enumeration.RaceSubType; import pcgen.cdom.enumeration.RaceType; @@ -91,6 +93,7 @@ import pcgen.cdom.inst.PCClassLevel; import pcgen.cdom.list.AbilityList; import pcgen.cdom.list.CompanionList; +import pcgen.cdom.list.DomainSpellList; import pcgen.cdom.reference.CDOMSingleRef; import pcgen.core.Ability.Nature; import pcgen.core.analysis.DomainApplication; @@ -120,7 +123,6 @@ import pcgen.core.prereq.PrereqHandler; import pcgen.core.prereq.Prerequisite; import pcgen.core.prereq.PrerequisiteOperator; -import pcgen.core.spell.PCSpellTracker; import pcgen.core.spell.Spell; import pcgen.core.system.GameModeRollMethod; import pcgen.core.utils.CoreUtility; @@ -234,9 +236,6 @@ // List of Kit objects private List<Kit> kitList = null; - // Spells - private PCSpellTracker spellTracker = null; - // // We don't want this list sorted until after it has been added // to the character, The reason is that sorting prevents @@ -410,7 +409,6 @@ addSpellBook(new SpellBook(Globals.INNATE_SPELL_BOOK_NAME, SpellBook.TYPE_INNATE_SPELLS)); populateSkills(SettingsHandler.getSkillsTab_IncludeSkills()); - spellTracker = new PCSpellTracker(this); setStringFor(StringKey.HANDED, PropertyFactory.getString("in_right")); //$NON-NLS-1$ } @@ -1041,16 +1039,6 @@ } /** - * Get the spell tracker - * - * @return spellTracker - */ - public PCSpellTracker getSpellTracker() - { - return spellTracker; - } - - /** * Get a list of types that apply to this character * * @return a List of Strings where each String is a type that the character @@ -6724,22 +6712,6 @@ return false; } - public Map<String, Integer> getSpellInfoMap(final String key1, - final String key2) - { - return spellTracker.getSpellInfoMap(key1, key2); - } - - public boolean isSpellLevelforKey(final String key, final int levelMatch) - { - return spellTracker.isSpellLevelforKey(key, levelMatch); - } - - public int getSpellLevelforKey(final String key, final int levelMatch) - { - return spellTracker.getSpellLevelforKey(key, levelMatch); - } - public void getSpellList() { // all non-spellcaster spells are added to race @@ -7455,14 +7427,14 @@ } } - final Map<String, Integer> domainMap = SpellLevel.getLevelInfo(this, aSpell); + final HashMapToList<CDOMList<Spell>, Integer> domainMap = this.getLevelInfo(aSpell); if (domainMap != null) { - for (String mKey : domainMap.keySet()) + for (CDOMList<?> spellList : domainMap.getKeySet()) { - if (mKey.startsWith("DOMAIN|")) + if (spellList instanceof DomainSpellList) { - tStr = "DOMAIN." + mKey.substring(7); + tStr = "DOMAIN." + spellList.getKeyName(); // bonuses.addAll( getBonusesTo("CASTERLEVEL", tStr) ); tBonus = (int) getTotalBonusTo("CASTERLEVEL", tStr); if (tBonus > 0) @@ -13517,7 +13489,7 @@ { boolean flag = false; - String src = obj.getSpellKey(this); + String src = obj.getVariableSource(); for (VariableKey vk : obj.getVariableKeys()) { @@ -14785,8 +14757,6 @@ aClone.kitList = new ArrayList<Kit>(); aClone.kitList.addAll(kitList); } - // Not sure what this is. It may need to be cloned. - aClone.spellTracker = spellTracker; aClone.templateAutoLanguages.addAll(templateAutoLanguages); aClone.templateLanguages.addAll(templateLanguages); aClone.setBio(new String(getBio())); @@ -18301,6 +18271,47 @@ return assocSupt.containsAssocList(o, alk); } + public HashMapToList<CDOMList<Spell>, Integer> getMasterLevelInfo(Spell sp) + { + HashMapToList<CDOMList<Spell>, Integer> hml = cache.get( + MapKey.SPELL_MASTER_INFO, sp); + if (hml == null) + { + hml = SpellLevel.getMasterLevelInfo(this, sp); + cache.addToMapFor(MapKey.SPELL_MASTER_INFO, sp, hml); + } + return hml; + } + + public HashMapToList<CDOMList<Spell>, Integer> getPCBasedLevelInfo(Spell sp) + { + HashMapToList<CDOMList<Spell>, Integer> hml = cache.get( + MapKey.SPELL_PC_INFO, sp); + if (hml == null) + { + hml = SpellLevel.getPCBasedLevelInfo(this, sp); + cache.addToMapFor(MapKey.SPELL_PC_INFO, sp, hml); + } + return hml; + } + + /** + * This method gets the information about the levels at which classes and + * domains may cast the spell. + * + * Modified 8 Sept 2003 by Sage_Sam for bug #801469 + * + * @return Map containing the class levels and domains that may cast the + * spell + * @param aPC + */ + public HashMapToList<CDOMList<Spell>, Integer> getLevelInfo(Spell sp) + { + HashMapToList<CDOMList<Spell>, Integer> levelInfo = getMasterLevelInfo(sp); + levelInfo.addAllLists(getPCBasedLevelInfo(sp)); + return levelInfo; + } + public CharacterSpell getCharacterSpellForSpell(PObject po, Spell spell) { List<CharacterSpell> cspells = Deleted: Trunk/pcgen/code/src/java/pcgen/core/SpellSupport.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/core/SpellSupport.java 2008-11-25 00:44:15 UTC (rev 8487) +++ Trunk/pcgen/code/src/java/pcgen/core/SpellSupport.java 2008-11-25 02:54:29 UTC (rev 8488) @@ -1,424 +0,0 @@ -/* - * Copyright 2001 (C) Bryan McRoberts <mer...@ya...> - * Copyright 2005 (C) Tom Parker <th...@so...> - * - * 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 - * - * Refactored out of PObject and PCSpellTracker July 23, 2005 - * - * Current Ver: $Revision$ - * Last Editor: $Author$ - * Last Edited: $Date$ - */ -package pcgen.core; - -import java.io.StringWriter; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; -import java.util.TreeMap; -import java.util.Map.Entry; - -import pcgen.base.util.DoubleKeyMap; -import pcgen.core.prereq.PrereqHandler; -import pcgen.core.prereq.Prerequisite; -import pcgen.persistence.PersistenceLayerException; -import pcgen.persistence.lst.output.prereq.PrerequisiteWriter; - -/** - * @author Tom Parker <th...@so...> - * - * Spell Support object for PObject (offloads code related to spell lists) - */ -public class SpellSupport implements Cloneable -{ - private static final String PIPE = "|"; - private static final String SPELLCASTER = "SPELLCASTER"; - private static final String CLASSSPELLCASTER = "CLASS|SPELLCASTER"; - private static final String ALL = "ALL"; - - private HashMap<String, Integer> spellLevelMap = - new HashMap<String, Integer>(); - private DoubleKeyMap<String, String, Info> spellInfoMap = - new DoubleKeyMap<String, String, Info>(); - private HashMap<String, List<Prerequisite>> preReqSpellLevelMap = - new HashMap<String, List<Prerequisite>>(); - - /** - * Clear the spell level map - */ - public void clearSpellLevelMap() - { - spellLevelMap.clear(); - } - - /** - * Put a spell level into the map - * - * @param tagType - * @param className - * @param spellName - * @param spellLevel - */ - public void putLevel(String tagType, String className, String spellName, - String spellLevel) - { - Integer lvl = Integer.valueOf(-1); - try - { - lvl = Integer.parseInt(spellLevel); - spellLevelMap.put(tagType + "|" + className + "|" + spellName, lvl); - } - catch (NumberFormatException nfe) - { - // TODO Handle Exception - } - } - - /** - * Returns true if the map contains the spell level - * @param tagType - * @param className - * @param spellName - * @return true if the map contains the spell level - */ - public boolean containsLevelFor(String tagType, String className, - String spellName) - { - return spellLevelMap.containsKey(tagType + "|" + className + "|" - + spellName); - } - - /** - * Put the spell info into the spell info map - * - * @param tagType - * @param spellName - * @param className - * @param spellLevel - */ - public void putInfo(String tagType, String spellName, String className, - String spellLevel) - { - spellInfoMap.put(tagType, spellName, new Info(className, Integer - .parseInt(spellLevel))); - } - - /** - * Class that holds spell info - */ - public class Info - { - /** name */ - public final String name; - /** spell level */ - public final int level; - - /** - * Constructor - * @param n - * @param l - */ - public Info(String n, int l) - { - name = n; - level = l; - } - } - - /** - * Clear the spell info map - */ - public void clearSpellInfoMap() - { - spellInfoMap.clear(); - } - - /** - * Returns true if the spell info map contains the info - * @param tagType The type of object to be assigned spells (e.g. CLASS or DOMAIN) - * @param spellName The name of the spell - * @return true if the spell info map contains the info - */ - public boolean containsInfoFor(String tagType, String spellName) - { - return spellInfoMap.containsKey(tagType, spellName); - } - - /** - * Get the info from the spell ifo map - * @param tagType The type of object to be assigned spells (e.g. CLASS or DOMAIN) - * @param spellName The name of the spell - * @return Info - */ - public Info getInfo(String tagType, String spellName) - { - return spellInfoMap.get(tagType, spellName); - } - - /** - * Add a spell level to the spell map and spell info into the info map - * - * @param tagType - * @param className - * @param spellName - * @param spellLevel - * @param preList - */ - public void addSpellLevel(String tagType, String className, - String spellName, String spellLevel, List<Prerequisite> preList) - { - preReqSpellLevelMap.put(tagType + "|" + className + "|" + spellName, - preList); - putLevel(tagType, className, spellName, spellLevel); - putInfo(tagType, spellName, className, spellLevel); - } - - /** - * Get the subset of the spell map that passes the PreReq - * - * @param levelMatch - * @param pc - * @return Map - */ - public Map<String, Integer> getSpellMapPassesPrereqs(int levelMatch, - PlayerCharacter pc) - { - final Map<String, Integer> tempMap = new HashMap<String, Integer>(); - - for (String key : spellLevelMap.keySet()) - { - final int levelInt = spellLevelMap.get(key); - - // levelMatch == -1 means get all spells - if (((levelMatch == -1) && (levelInt >= 0)) - || ((levelMatch >= 0) && (levelInt == levelMatch))) - { - if (preReqSpellLevelMap.containsKey(key)) - { - if (key.startsWith(CLASSSPELLCASTER)) - { - String spellType = key.substring(18); - spellType = - spellType.substring(0, spellType.indexOf(PIPE)); - - if (ALL.equals(spellType) - || pc.isSpellCaster(spellType, 1)) - { - if (PrereqHandler.passesAll(preReqSpellLevelMap - .get(key), pc, null)) - { - for (PCClass pcClass : pc.getClassList()) - { - if (pcClass.getSpellType() - .equals(spellType) - || ALL.equals(spellType)) - { - StringBuffer tempSb = - new StringBuffer(); - tempSb.append(pcClass.getSpellKey(pc)) - .append(PIPE).append( - key.substring(key - .lastIndexOf(PIPE) + 1)); - tempMap - .put(tempSb.toString(), levelInt); - } - } - } - } - } - else if (PrereqHandler.passesAll(preReqSpellLevelMap - .get(key), pc, null)) - { - tempMap.put(key, levelInt); - } - } - } - } - return tempMap; - } - - /** - * Get the subset Map of infos that meet the PreReq - * @param key1 - * @param key2 - * @param pc - * @return Map - */ - public Map<String, Integer> getSpellInfoMapPassesPrereqs(String key1, - String key2, PlayerCharacter pc) - { - final Map<String, Integer> tempMap = new HashMap<String, Integer>(); - - if (spellInfoMap.containsKey(key1, key2)) - { - Info si = spellInfoMap.get(key1, key2); - StringBuffer keysb = new StringBuffer(); - keysb.append(key1).append(PIPE).append(si.name).append(PIPE) - .append(key2); - String key = keysb.toString(); - if (preReqSpellLevelMap.containsKey(key)) - { - if (si.name.startsWith(SPELLCASTER)) - { - final String spellType = si.name.substring(12); - - if (ALL.equals(spellType) || pc.isSpellCaster(spellType, 1)) - { - if (PrereqHandler.passesAll(preReqSpellLevelMap - .get(key), pc, null)) - { - for (PCClass pcClass : pc.getClassList()) - { - if (pcClass.getSpellType().equals(spellType) - || ALL.equals(spellType)) - { - tempMap.put(pcClass.getSpellKey(pc), - si.level); - } - } - } - } - } - else if (PrereqHandler.passesAll(preReqSpellLevelMap.get(key), - pc, null)) - { - StringBuffer tempSb = new StringBuffer(); - tempSb.append(key1).append(PIPE).append(si.name); - tempMap.put(tempSb.toString(), si.level); - } - } - } - - return tempMap; - } - - - @Override - public SpellSupport clone() throws CloneNotSupportedException - { - SpellSupport ss = (SpellSupport) super.clone(); - ss.spellInfoMap = spellInfoMap.clone(); - ss.preReqSpellLevelMap = - new HashMap<String, List<Prerequisite>>(preReqSpellLevelMap); - ss.spellLevelMap = new HashMap<String, Integer>(spellLevelMap); - return ss; - } - - /** - * Get the LST syntax that represents the spells assigned via SPELLLEVEL tags. - * @return The LST syntax - */ - public String getPCCText() - { - StringBuffer txt = new StringBuffer(); - - SortedMap<String, StringBuffer> spellOutputMap = - new TreeMap<String, StringBuffer>(); - - // Iterate through the spellinfo map to build the list of spells - // Outputing any that have prereqs as we can't group them. - Set<String> tagTypeSet = spellInfoMap.getKeySet(); - for (String tagType : tagTypeSet) - { - Set<String> spellNameSet = spellInfoMap.getSecondaryKeySet(tagType); - for (String spellName : spellNameSet) - { - Info spellInfo = spellInfoMap.get(tagType, spellName); - List<Prerequisite> preReqList = - preReqSpellLevelMap.get(tagType + "|" + spellInfo.name - + "|" + spellName); - if (preReqList == null || preReqList.isEmpty()) - { - StringBuffer key = new StringBuffer(); - key.append(tagType); - key.append("|").append(spellInfo.name); - key.append("=").append(spellInfo.level); - StringBuffer sb = spellOutputMap.get(key.toString()); - if (sb == null) - { - sb = new StringBuffer(); - spellOutputMap.put(key.toString(), sb); - } - else - { - sb.append(','); - } - sb.append(spellName); - } - else - { - if (txt.length() > 0) - { - txt.append('\t'); - } - txt.append(getSpellLevelPccText(tagType, spellName, - spellInfo, preReqList)); - } - } - } - - // Iterate through the spellOutputMap outputing the spells - for (Entry<String, StringBuffer> me : spellOutputMap.entrySet()) - { - if (txt.length() > 0) - { - txt.append('\t'); - } - txt.append("SPELLLEVEL:").append(me.getKey()); - txt.append("|"); - txt.append(me.getValue()); - } - - return txt.toString(); - } - - /** - * Build the LST defintiion text for the supplied spell. - * @param tagType The type of object to be assigned spells (e.g. CLASS or DOMAIN) - * @param spellName The name of the spell - * @param spellInfo The class name and level - * @param preReqList The spell's prewrequisites - * @return The string representation fo the spell. - */ - private String getSpellLevelPccText(String tagType, String spellName, - Info spellInfo, List<Prerequisite> preReqList) - { - StringBuffer txt = new StringBuffer(); - txt.append("SPELLLEVEL:").append(tagType); - txt.append("|").append(spellInfo.name); - txt.append("=").append(spellInfo.level); - txt.append("|").append(spellName); - final StringWriter writer = new StringWriter(); - for (Prerequisite prereq : preReqList) - { - final PrerequisiteWriter prereqWriter = new PrerequisiteWriter(); - try - { - writer.write("|"); - prereqWriter.write(writer, prereq); - } - catch (PersistenceLayerException e1) - { - e1.printStackTrace(); - } - } - txt.append(writer); - - return txt.toString(); - } -} Modified: Trunk/pcgen/code/src/java/pcgen/core/analysis/DomainApplication.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/core/analysis/DomainApplication.java 2008-11-25 00:44:15 UTC (rev 8487) +++ Trunk/pcgen/code/src/java/pcgen/core/analysis/DomainApplication.java 2008-11-25 02:54:29 UTC (rev 8488) @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; import pcgen.base.formula.Formula; @@ -29,12 +30,13 @@ import pcgen.cdom.enumeration.AssociationKey; import pcgen.cdom.enumeration.AssociationListKey; import pcgen.cdom.enumeration.IntegerKey; +import pcgen.cdom.enumeration.ObjectKey; +import pcgen.cdom.list.DomainSpellList; import pcgen.core.CharacterDomain; import pcgen.core.Domain; import pcgen.core.Globals; import pcgen.core.PCClass; import pcgen.core.PlayerCharacter; -import pcgen.core.SpellSupport; import pcgen.core.character.CharacterSpell; import pcgen.core.chooser.ChooserUtilities; import pcgen.core.prereq.PrereqHandler; @@ -80,14 +82,18 @@ && (aClass .getSafe(IntegerKey.KNOWN_SPELLS_FROM_SPECIALTY) == 0)) { - final List<Spell> aList = Globals.getSpellsIn(-1, "", - keyName); + DomainSpellList domainSpellList = d + .get(ObjectKey.DOMAIN_SPELLLIST); + final List<Spell> aList = Globals.getSpellsIn(-1, + Collections.singletonList(domainSpellList)); for (Spell gcs : aList) { - if (SpellLevel.levelForKey(gcs, "DOMAIN", keyName, pc) < maxLevel) + if (SpellLevel + .getFirstLvlForKey(gcs, domainSpellList, pc) < maxLevel) { - pc.setAssoc(aClass, AssociationKey.DOMAIN_SPELL_COUNT, 1); + pc.setAssoc(aClass, + AssociationKey.DOMAIN_SPELL_COUNT, 1); break; } } @@ -154,8 +160,8 @@ for (int aLevel = minLevel; aLevel <= maxLevel; aLevel++) { - List<Spell> domainSpells = Globals.getSpellsIn(aLevel, "", d - .getKeyName()); + List<Spell> domainSpells = Globals.getSpellsIn(aLevel, Collections + .singletonList(d.get(ObjectKey.DOMAIN_SPELLLIST))); for (Spell spell : domainSpells) { Modified: Trunk/pcgen/code/src/java/pcgen/core/analysis/SpellLevel.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/core/analysis/SpellLevel.java 2008-11-25 00:44:15 UTC (rev 8487) +++ Trunk/pcgen/code/src/java/pcgen/core/analysis/SpellLevel.java 2008-11-25 02:54:29 UTC (rev 8488) @@ -2,15 +2,17 @@ import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; +import java.util.Set; +import java.util.TreeSet; +import pcgen.base.util.HashMapToList; import pcgen.cdom.base.AssociatedPrereqObject; +import pcgen.cdom.base.CDOMList; import pcgen.cdom.base.CDOMObject; import pcgen.cdom.base.CDOMReference; import pcgen.cdom.base.MasterListInterface; +import pcgen.cdom.base.PrereqObject; import pcgen.cdom.enumeration.AssociationKey; import pcgen.cdom.enumeration.ObjectKey; import pcgen.cdom.list.ClassSpellList; @@ -21,278 +23,67 @@ import pcgen.core.PlayerCharacter; import pcgen.core.prereq.PrereqHandler; import pcgen.core.spell.Spell; -import pcgen.rules.context.LoadContext; -import pcgen.util.Logging; public class SpellLevel { - /** - * This method gets the information about the levels at which classes and - * domains may cast the spell. - * - * Modified 8 Sept 2003 by Sage_Sam for bug #801469 - * - * @return Map containing the class levels and domains that may cast the - * spell - * @param aPC - */ - public static Map<String, Integer> getLevelInfo(final PlayerCharacter aPC, - Spell sp) + public static boolean levelForKeyContains(Spell sp, + List<? extends CDOMList<Spell>> lists, int levelMatch, + PlayerCharacter aPC) { - Map<String, Integer> wLevelInfo = new HashMap<String, Integer>(); - - MasterListInterface masterLists = Globals.getMasterLists(); - for (CDOMReference list : masterLists.getActiveLists()) + Set<Integer> resultList = new TreeSet<Integer>(); + HashMapToList<CDOMList<Spell>, Integer> levelInfo = aPC.getMasterLevelInfo(sp); + for (CDOMList<Spell> spellList : lists) { - Collection<AssociatedPrereqObject> assoc = masterLists - .getAssociations(list, sp); - if (assoc != null) + List<Integer> levels = levelInfo.getListFor(spellList); + if (levels != null) { - String type = ClassSpellList.class.equals(list - .getReferenceClass()) ? "CLASS" : "DOMAIN"; - for (AssociatedPrereqObject apo : assoc) - { - Integer lvl = apo - .getAssociation(AssociationKey.SPELL_LEVEL); - wLevelInfo.put(type + "|" + list.getLSTformat(), lvl); - } + resultList.addAll(levels); } - } - - if (aPC != null) - { - wLevelInfo.putAll(aPC.getSpellInfoMap("CLASS", sp.getKeyName())); - wLevelInfo.putAll(aPC.getSpellInfoMap("DOMAIN", sp.getKeyName())); - } - return wLevelInfo; - } - - public static boolean levelForKeyContains(Spell sp, final String key, - final int levelMatch, final PlayerCharacter aPC) - { - // should consist of CLASS|name and DOMAIN|name pairs - final StringTokenizer aTok = new StringTokenizer(key, "|", false); - final int[] levelInt1 = new int[aTok.countTokens() / 2]; - int i1 = 0; - - while (aTok.hasMoreTokens()) - { - final String objectType = aTok.nextToken(); - Class<? extends CDOMObject> listClass = "CLASS".equals(objectType) ? ClassSpellList.class - : DomainSpellList.class; - LoadContext context = Globals.getContext(); - if (!aTok.hasMoreTokens()) + if (resultList.isEmpty()) { - Logging.errorPrint("SEVERE: Key " + key - + " had even number of |"); - Thread.dumpStack(); - break; - } - final String objectName = aTok.nextToken(); - CDOMObject spellList = context.ref - .silentlyGetConstructedCDOMObject(listClass, objectName); - int result = -1; - if (spellList == null) - { - Logging.debugPrint("Skipping " + objectType + " " + objectName); - } - else - { - MasterListInterface masterLists = Globals.getMasterLists(); - for (CDOMReference list : masterLists.getActiveLists()) + levelInfo = aPC.getPCBasedLevelInfo(sp); + levels = levelInfo.getListFor(spellList); + if (levels != null) { - if (list.contains(spellList)) - { - Collection<AssociatedPrereqObject> assoc = masterLists - .getAssociations(list, sp); - if (assoc != null) - { - for (AssociatedPrereqObject apo : assoc) - { - if (PrereqHandler.passesAll(apo - .getPrerequisiteList(), aPC, sp)) - { - result = apo - .getAssociation(AssociationKey.SPELL_LEVEL); - } - } - } - } + resultList.addAll(levels); } - - if (aPC != null && result == -1) - { - HashMap<String, Integer> wLevelInfo = new HashMap<String, Integer>(); - wLevelInfo.putAll(aPC.getSpellInfoMap("CLASS", sp - .getKeyName())); - wLevelInfo.putAll(aPC.getSpellInfoMap("DOMAIN", sp - .getKeyName())); - if (wLevelInfo.size() != 0) - { - Integer lvl = wLevelInfo.get(objectType + "|" - + objectName); - - if (lvl == null) - { - lvl = wLevelInfo.get(objectType + "|ALL"); - } - - if ((lvl == null) && objectType.equals("CLASS")) - { - final PCClass aClass = Globals.getContext().ref - .silentlyGetConstructedCDOMObject( - PCClass.class, objectName); - - if (aClass != null) - { - final StringTokenizer aTok1 = new StringTokenizer( - aClass.getType(), ".", false); - - while (aTok1.hasMoreTokens() && (lvl == null)) - { - lvl = wLevelInfo.get(objectType + "|TYPE." - + aTok1.nextToken()); - } - } - } - - if (lvl != null) - { - result = lvl.intValue(); - } - } - - } } - - levelInt1[i1++] = result; } - - final int[] levelInt = levelInt1; - - for (int i = 0; i < levelInt.length; ++i) - { - // always match if levelMatch==-1 - if (((levelMatch == -1) && (levelInt[i] >= 0)) - || ((levelMatch >= 0) && (levelInt[i] == levelMatch))) - { - return true; - } - } - - // If it's not regularly on the list, check if some SPELLLEVEL tag added - // it. - if (aPC != null) - { - return (aPC.isSpellLevelforKey(key + "|" + sp.getKeyName(), - levelMatch)); - } - return false; + return levelMatch == -1 && !resultList.isEmpty() || levelMatch >= 0 + && resultList.contains(levelMatch); } - public static Integer[] levelForKey(Spell sp, final String key, - final PlayerCharacter aPC) + public static Integer[] levelForKey(Spell sp, + List<? extends CDOMList<Spell>> lists, PlayerCharacter aPC) { List<Integer> list = new ArrayList<Integer>(); - // If it's not regularly on the list, check if some SPELLLEVEL tag added - // it. - if (aPC != null) + for (CDOMList<Spell> spellList : lists) { - list.add(aPC.getSpellLevelforKey(key + "|" + sp.getKeyName(), -1)); + list.add(getFirstLvlForKey(sp, spellList, aPC)); } - else - { - list.add(-1); - } - // should consist of CLASS|name and DOMAIN|name pairs - final StringTokenizer aTok = new StringTokenizer(key, "|", false); - - while (aTok.hasMoreTokens()) - { - final String objectType = aTok.nextToken(); - - if (aTok.hasMoreTokens()) - { - list.add(levelForKey(sp, objectType, aTok.nextToken(), aPC)); - } - } - return list.toArray(new Integer[list.size()]); } - public static int levelForKey(Spell sp, final String mType, - final String sType, final PlayerCharacter aPC) + public static int getFirstLvlForKey(Spell sp, CDOMList<Spell> list, + PlayerCharacter aPC) { - int result = -1; - final Map<String, Integer> wLevelInfo = getLevelInfo(aPC, sp); + HashMapToList<CDOMList<Spell>, Integer> wLevelInfo = aPC.getLevelInfo(sp); if ((wLevelInfo != null) && (wLevelInfo.size() != 0)) { - Integer lvl = wLevelInfo.get(mType + "|" + sType); - - if (lvl == null) + List<Integer> levelList = wLevelInfo.getListFor(list); + if (levelList != null) { - lvl = wLevelInfo.get(mType + "|ALL"); + // We assume those calling this method know what they are doing! + return levelList.get(0); } - - if ((lvl == null) && mType.equals("CLASS")) - { - final PCClass aClass = Globals.getContext().ref - .silentlyGetConstructedCDOMObject(PCClass.class, sType); - - if (aClass != null) - { - final StringTokenizer aTok = new StringTokenizer(aClass - .getType(), ".", false); - - while (aTok.hasMoreTokens() && (lvl == null)) - { - lvl = wLevelInfo.get(mType + "|TYPE." - + aTok.nextToken()); - } - } - } - - if (lvl != null) - { - result = lvl.intValue(); - } } - - return result; + return -1; } /** - * Assess if this spell is of the requested level for any class. - * - * @param level - * The level to be checked. - * @return True if the spell is the requested level. - */ - public static boolean isLevel(Spell sp, final int level) - { - MasterListInterface masterLists = Globals.getMasterLists(); - for (CDOMReference list : masterLists.getActiveLists()) - { - Collection<AssociatedPrereqObject> assoc = masterLists - .getAssociations(list, sp); - if (assoc != null) - { - for (AssociatedPrereqObject apo : assoc) - { - if (level == apo.getAssociation(AssociationKey.SPELL_LEVEL)) - { - return true; - } - } - } - } - return false; - } - - /** * isLevel(int aLevel) * * @param aLevel @@ -300,8 +91,7 @@ * @param aPC * @return true if the spell is of the given level in any spell list */ - public static boolean isLevel(Spell sp, final int aLevel, - final PlayerCharacter aPC) + public static boolean isLevel(Spell sp, int aLevel, PlayerCharacter aPC) { Integer levelKey = Integer.valueOf(aLevel); MasterListInterface masterLists = Globals.getMasterLists(); @@ -314,10 +104,14 @@ { for (AssociatedPrereqObject apo : assoc) { - if (levelKey.equals(apo - .getAssociation(AssociationKey.SPELL_LEVEL))) + if (PrereqHandler.passesAll(apo.getPrerequisiteList(), aPC, + sp)) { - return true; + if (levelKey.equals(apo + .getAssociation(AssociationKey.SPELL_LEVEL))) + { + return true; + } } } } @@ -332,10 +126,14 @@ { for (AssociatedPrereqObject apo : assoc) { - if (levelKey.equals(apo - .getAssociation(AssociationKey.SPELL_LEVEL))) + if (PrereqHandler.passesAll(apo.getPrerequisiteList(), aPC, + sp)) { - return true; + if (levelKey.equals(apo + .getAssociation(AssociationKey.SPELL_LEVEL))) + { + return true; + } } } } @@ -343,46 +141,101 @@ return false; } - public static String getLevelString(Spell sp) + public static int getFirstLevelForKey(Spell sp, + List<? extends CDOMList<Spell>> lists, PlayerCharacter aPC) { - StringBuilder sb = new StringBuilder(); - boolean needsComma = false; + Integer[] levelInt = levelForKey(sp, lists, aPC); + int result = -1; + + if (levelInt.length > 0) + { + for (int i = 0; i < levelInt.length; i++) + if (levelInt[i] > -1) + return levelInt[i]; + } + + return result; + } + + public static HashMapToList<CDOMList<Spell>, Integer> getMasterLevelInfo( + PlayerCharacter aPC, Spell sp) + { + HashMapToList<CDOMList<Spell>, Integer> levelInfo = new HashMapToList<CDOMList<Spell>, Integer>(); + MasterListInterface masterLists = Globals.getMasterLists(); - for (CDOMReference list : masterLists.getActiveLists()) + for (CDOMReference<? extends CDOMList> ref : masterLists + .getActiveLists()) { - Collection<AssociatedPrereqObject> assoc = masterLists - .getAssociations(list, sp); - if (assoc != null) + for (CDOMList list : ref.getContainedObjects()) { - for (AssociatedPrereqObject apo : assoc) + if (list instanceof ClassSpellList + || list instanceof DomainSpellList) { - if (needsComma) + Collection<AssociatedPrereqObject> assoc = masterLists + .getAssociations(list, sp); + for (AssociatedPrereqObject apo : assoc) { - sb.append(", "); + // TODO This null for source is incorrect! + if (PrereqHandler.passesAll(apo.getPrerequisiteList(), + aPC, null)) + { + Integer lvl = apo + .getAssociation(AssociationKey.SPELL_LEVEL); + levelInfo.addToListFor(list, lvl); + } } - needsComma = true; - sb.append(list.getLSTformat()); - sb.append(apo.getAssociation(AssociationKey.SPELL_LEVEL)); } } } - return sb.toString(); + return levelInfo; } - public static int getFirstLevelForKey(Spell sp, final String key, - final PlayerCharacter aPC) + public static HashMapToList<CDOMList<Spell>, Integer> getPCBasedLevelInfo(PlayerCharacter pc, Spell sp) { - final Integer[] levelInt = levelForKey(sp, key, aPC); - int result = -1; - - if (levelInt.length > 0) + HashMapToList<CDOMList<Spell>, Integer> levelInfo = new HashMapToList<CDOMList<Spell>, Integer>(); + for (CDOMObject cdo : pc.getCDOMObjectList()) { - for (int i = 0; i < levelInt.length; i++) - if (levelInt[i] > -1) - return levelInt[i]; + Collection<CDOMReference<? extends CDOMList<? extends PrereqObject>>> listrefs = cdo + .getModifiedLists(); + for (CDOMReference<? extends CDOMList<? extends PrereqObject>> ref : listrefs) + { + Collection<? extends CDOMList> lists = ref + .getContainedObjects(); + for (CDOMList<Spell> list : lists) + { + if (list instanceof ClassSpellList + || list instanceof DomainSpellList) + { + CDOMReference<? extends CDOMList<Spell>> spelllistref = (CDOMReference<? extends CDOMList<Spell>>) ref; + Collection<CDOMReference<Spell>> mods = cdo + .getListMods(spelllistref); + for (CDOMReference<Spell> spellref : mods) + { + if (spellref.contains(sp)) + { + Collection<AssociatedPrereqObject> listAssocs = cdo + .getListAssociations(spelllistref, + spellref); + for (AssociatedPrereqObject apo : listAssocs) + { + // TODO This null for source is + // incorrect! + if (PrereqHandler.passesAll(apo + .getPrerequisiteList(), pc, null)) + { + Integer lvl = apo + .getAssociation(AssociationKey.SPELL_LEVEL); + levelInfo.addToListFor(list, lvl); + } + } + } + } + } + } + } + } - - return result; + return levelInfo; } } Modified: Trunk/pcgen/code/src/java/pcgen/core/chooser/SpellsChoiceManager.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/core/chooser/SpellsChoiceManager.java 2008-11-25 00:44:15 UTC (rev 8487) +++ Trunk/pcgen/code/src/java/pcgen/core/chooser/SpellsChoiceManager.java 2008-11-25 02:54:29 UTC (rev 8488) @@ -24,18 +24,22 @@ package pcgen.core.chooser; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; +import pcgen.base.util.HashMapToList; +import pcgen.cdom.base.CDOMList; import pcgen.cdom.enumeration.ListKey; +import pcgen.cdom.list.ClassSpellList; +import pcgen.cdom.list.DomainSpellList; import pcgen.core.Globals; import pcgen.core.PCClass; import pcgen.core.PObject; import pcgen.core.PlayerCharacter; -import pcgen.core.SpellSupport; import pcgen.core.analysis.SpellLevel; import pcgen.core.character.CharacterSpell; import pcgen.core.spell.Spell; @@ -85,14 +89,18 @@ List<Spell> localList = new ArrayList<Spell>(); if (token.startsWith("DOMAIN=") || token.startsWith("DOMAIN.")) { - appendSpells(new TypeKeyFilter("DOMAIN", - token.substring(7), null), aPc, localList); + DomainSpellList dsl = Globals.getContext().ref + .silentlyGetConstructedCDOMObject( + DomainSpellList.class, token.substring(7)); + appendSpells(new TypeKeyFilter(dsl, null), aPc, localList); } else if (token.startsWith("CLASS=") || token.startsWith("CLASS.")) { - appendSpells(new TypeKeyFilter("CLASS", token.substring(6), - null), aPc, localList); + ClassSpellList csl = Globals.getContext().ref + .silentlyGetConstructedCDOMObject( + ClassSpellList.class, token.substring(6)); + appendSpells(new TypeKeyFilter(csl, null), aPc, localList); } else if (token.startsWith("ANY")) { @@ -107,7 +115,7 @@ + " did not have matching brackets"); } r = getRestriction("ANY", token.substring( - bracketLoc + 1, token.length() - 1), aPc); + bracketLoc + 1, token.length() - 1), aPc); } appendSpells(new AnyFilter(r), aPc, localList); } @@ -158,8 +166,10 @@ .substring(bracketLoc + 1, token.length() - 1), aPc); } - appendSpells(new TypeKeyFilter("DOMAIN", domainName, r), - aPc, localList); + DomainSpellList dsl = Globals.getContext().ref + .silentlyGetConstructedCDOMObject( + DomainSpellList.class, domainName); + appendSpells(new TypeKeyFilter(dsl, r), aPc, localList); } else if (token.startsWith("CLASSLIST=")) { @@ -183,8 +193,10 @@ .substring(bracketLoc + 1, token.length() - 1), aPc); } - appendSpells(new TypeKeyFilter("CLASS", className, r), aPc, - localList); + ClassSpellList csl = Globals.getContext().ref + .silentlyGetConstructedCDOMObject( + ClassSpellList.class, className); + appendSpells(new TypeKeyFilter(csl, r), aPc, localList); } else if (token.startsWith("SCHOOL=")) { @@ -343,24 +355,22 @@ private class TypeKeyFilter implements SpellFilter { - private final String listtype; - private final String listname; + private final CDOMList<Spell> spelllist; private final Restriction res; private final String defaultbook; - public TypeKeyFilter(String ltype, String listkey, Restriction r) + public TypeKeyFilter(CDOMList<Spell> list, Restriction r) { defaultbook = Globals.getDefaultSpellBook(); - listtype = ltype; - listname = listkey; res = r; + spelllist = list; } public void conditionallyAdd(Spell spell, PlayerCharacter pc, List<Spell> availableList) { - String listkey = listtype + "|" + listname; - LEVEL: for (int level : SpellLevel.levelForKey(spell, listkey, pc)) + LEVEL: for (int level : SpellLevel.levelForKey(spell, Collections + .singletonList(spelllist), pc)) { if (level < 0) { @@ -420,30 +430,42 @@ { return; } - Map<String, Integer> levelInfo = SpellLevel.getLevelInfo(pc, spell); + HashMapToList<CDOMList<Spell>, Integer> levelInfo = pc.getLevelInfo(spell); boolean useDomain = "DIVINE".equalsIgnoreCase(listname); - for (Map.Entry<String, Integer> me : levelInfo.entrySet()) + for (CDOMList<Spell> spellList : levelInfo.getKeySet()) { - if (useDomain && me.getKey().startsWith("DOMAIN|")) + ... [truncated message content] |