From: <th...@us...> - 2010-07-13 22:36:09
|
Revision: 12559 http://pcgen.svn.sourceforge.net/pcgen/?rev=12559&view=rev Author: thpr Date: 2010-07-13 22:36:01 +0000 (Tue, 13 Jul 2010) Log Message: ----------- Finish up class skill facets Modified Paths: -------------- Trunk/pcgen/code/pluginbuild.xml Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/AssociationListKey.java Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/ListKey.java Trunk/pcgen/code/src/java/pcgen/cdom/facet/FacetInitialization.java Trunk/pcgen/code/src/java/pcgen/cdom/facet/GlobalSkillCostFacet.java Trunk/pcgen/code/src/java/pcgen/cdom/helper/ClassSkillChoiceActor.java Trunk/pcgen/code/src/java/pcgen/core/PCClass.java Trunk/pcgen/code/src/java/pcgen/core/PlayerCharacter.java Trunk/pcgen/code/src/java/pcgen/core/analysis/SkillCostCalc.java Trunk/pcgen/code/src/java/plugin/lsttokens/CcskillLst.java Trunk/pcgen/code/src/java/plugin/lsttokens/domain/CskillToken.java Trunk/pcgen/code/src/java/plugin/lsttokens/pcclass/level/CskillToken.java Trunk/pcgen/code/src/test/pcgen/core/prereq/PreCSkillTest.java Added Paths: ----------- Trunk/pcgen/code/src/java/pcgen/cdom/facet/LocalAddedSkillCostFacet.java Trunk/pcgen/code/src/java/pcgen/cdom/facet/LocalSkillCostFacet.java Trunk/pcgen/code/src/java/plugin/lsttokens/domain/CcskillToken.java Trunk/pcgen/code/src/java/plugin/lsttokens/pcclass/CcskillToken.java Trunk/pcgen/code/src/java/plugin/lsttokens/pcclass/level/CcskillToken.java Modified: Trunk/pcgen/code/pluginbuild.xml =================================================================== --- Trunk/pcgen/code/pluginbuild.xml 2010-07-13 21:56:04 UTC (rev 12558) +++ Trunk/pcgen/code/pluginbuild.xml 2010-07-13 22:36:01 UTC (rev 12559) @@ -3028,6 +3028,13 @@ </patternset> </fileset> </jar> + <jar jarfile="${lstplugins.dir}/ClassLstToken-CCSKILL.jar" manifest="${src.java.dir}/plugin/lsttokens/manifest.mf"> + <fileset dir="${build.classes.dir}"> + <patternset> + <include name="plugin/lsttokens/pcclass/CcskillToken.class" /> + </patternset> + </fileset> + </jar> <jar jarfile="${lstplugins.dir}/ClassLstToken-CSKILL.jar" manifest="${src.java.dir}/plugin/lsttokens/manifest.mf"> <fileset dir="${build.classes.dir}"> <patternset> @@ -3262,6 +3269,13 @@ </patternset> </fileset> </jar> + <jar jarfile="${lstplugins.dir}/ClassLevelLstToken-CCSKILL.jar" manifest="${src.java.dir}/plugin/lsttokens/manifest.mf"> + <fileset dir="${build.classes.dir}"> + <patternset> + <include name="plugin/lsttokens/pcclass/level/CcskillToken.class" /> + </patternset> + </fileset> + </jar> <jar jarfile="${lstplugins.dir}/ClassLevelLstToken-CSKILL.jar" manifest="${src.java.dir}/plugin/lsttokens/manifest.mf"> <fileset dir="${build.classes.dir}"> <patternset> @@ -3435,6 +3449,13 @@ <target name="jar-lst-domain-plugins" depends="makeplugindirs" description="Build (Link) Do Lst Token plugin jar files"> <!-- Domain tokens--> + <jar jarfile="${lstplugins.dir}/DomainLstToken-CCSKILL.jar" manifest="${src.java.dir}/plugin/lsttokens/manifest.mf"> + <fileset dir="${build.classes.dir}"> + <patternset> + <include name="plugin/lsttokens/domain/CcskillToken.class" /> + </patternset> + </fileset> + </jar> <jar jarfile="${lstplugins.dir}/DomainLstToken-CSKILL.jar" manifest="${src.java.dir}/plugin/lsttokens/manifest.mf"> <fileset dir="${build.classes.dir}"> <patternset> Modified: Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/AssociationListKey.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/AssociationListKey.java 2010-07-13 21:56:04 UTC (rev 12558) +++ Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/AssociationListKey.java 2010-07-13 22:36:01 UTC (rev 12559) @@ -86,10 +86,6 @@ public static final AssociationListKey<CDOMListObject<Spell>> CLASSSPELLLIST = new AssociationListKey<CDOMListObject<Spell>>(); - public static final AssociationListKey<Skill> CCSKILL = new AssociationListKey<Skill>(); - - public static final AssociationListKey<Skill> CSKILL = new AssociationListKey<Skill>(); - public static final AssociationListKey<Ability> ADDED_FEAT = new AssociationListKey<Ability>(); public static final AssociationListKey<CDOMList<Spell>> SPELL_LIST_CACHE = new AssociationListKey<CDOMList<Spell>>(); @@ -146,8 +142,6 @@ public static final AssociationListKey<String> CHOOSE_NOCHOICE = new AssociationListKey<String>(); public static final AssociationListKey<AbilitySelection> CHOOSE_FEATSELECTION = new AssociationListKey<AbilitySelection>(); - - public static final AssociationListKey<Skill> PARENTCSKILL = new AssociationListKey<Skill>(); private static CaseInsensitiveMap<AssociationListKey<?>> map = null; Modified: Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/ListKey.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/ListKey.java 2010-07-13 21:56:04 UTC (rev 12558) +++ Trunk/pcgen/code/src/java/pcgen/cdom/enumeration/ListKey.java 2010-07-13 22:36:01 UTC (rev 12559) @@ -255,7 +255,8 @@ public static final ListKey<String> HIDDEN_Skill = new ListKey<String>(); public static final ListKey<CDOMReference<Language>> AUTO_LANGUAGE = new ListKey<CDOMReference<Language>>(); public static final ListKey<CDOMReference<Skill>> CLASS_SKILL = new ListKey<CDOMReference<Skill>>(); - public static final ListKey<CDOMReference<Skill>> PARENTCSKILL = new ListKey<CDOMReference<Skill>>(); + public static final ListKey<CDOMReference<Skill>> LOCALCSKILL = new ListKey<CDOMReference<Skill>>(); + public static final ListKey<CDOMReference<Skill>> LOCALCCSKILL = new ListKey<CDOMReference<Skill>>(); private static CaseInsensitiveMap<ListKey<?>> map = null; Modified: Trunk/pcgen/code/src/java/pcgen/cdom/facet/FacetInitialization.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/cdom/facet/FacetInitialization.java 2010-07-13 21:56:04 UTC (rev 12558) +++ Trunk/pcgen/code/src/java/pcgen/cdom/facet/FacetInitialization.java 2010-07-13 22:36:01 UTC (rev 12559) @@ -132,6 +132,8 @@ .getFacet(EquipSetFacet.class); GlobalSkillCostFacet globalSkillCostFacet = FacetLibrary .getFacet(GlobalSkillCostFacet.class); + LocalSkillCostFacet localSkillCostFacet = FacetLibrary + .getFacet(LocalSkillCostFacet.class); ChooseDriverFacet chooseDriverFacet = FacetLibrary .getFacet(ChooseDriverFacet.class); @@ -181,6 +183,10 @@ deityFacet.addDataFacetChangeListener(deityWeaponProfFacet); templateFacet.addDataFacetChangeListener(addLevelFacet); + classFacet.addDataFacetChangeListener(localSkillCostFacet); + domainFacet.addDataFacetChangeListener(localSkillCostFacet); + classLevelFacet.addDataFacetChangeListener(localSkillCostFacet); + charObjectFacet.addDataFacetChangeListener(naturalWeaponFacet); naturalWeaponFacet.addDataFacetChangeListener(equipmentFacet); naturalWeaponFacet.addDataFacetChangeListener(userEquipmentFacet); Modified: Trunk/pcgen/code/src/java/pcgen/cdom/facet/GlobalSkillCostFacet.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/cdom/facet/GlobalSkillCostFacet.java 2010-07-13 21:56:04 UTC (rev 12558) +++ Trunk/pcgen/code/src/java/pcgen/cdom/facet/GlobalSkillCostFacet.java 2010-07-13 22:36:01 UTC (rev 12559) @@ -60,6 +60,13 @@ add(id, sk, SkillCost.CLASS, cdo); } } + for (CDOMReference<Skill> ref : cdo.getSafeListFor(ListKey.CCSKILL)) + { + for (Skill sk : ref.getContainedObjects()) + { + add(id, sk, SkillCost.CROSS_CLASS, cdo); + } + } } /** Added: Trunk/pcgen/code/src/java/pcgen/cdom/facet/LocalAddedSkillCostFacet.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/cdom/facet/LocalAddedSkillCostFacet.java (rev 0) +++ Trunk/pcgen/code/src/java/pcgen/cdom/facet/LocalAddedSkillCostFacet.java 2010-07-13 22:36:01 UTC (rev 12559) @@ -0,0 +1,179 @@ +/* + * Copyright (c) Thomas Parker, 2010. + * + * This program 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 program 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ +package pcgen.cdom.facet; + +import java.util.IdentityHashMap; +import java.util.Map; +import java.util.Set; + +import pcgen.base.util.WrappedMapSet; +import pcgen.cdom.base.CDOMObject; +import pcgen.cdom.enumeration.CharID; +import pcgen.cdom.enumeration.SkillCost; +import pcgen.core.PCClass; +import pcgen.core.Skill; + +public class LocalAddedSkillCostFacet +{ + private final Class<?> thisClass = getClass(); + + /** + * Returns the type-safe CacheInfo for this LocalSkillCostFacet and the + * given CharID. Will return a new, empty CacheInfo if no Skill information + * has been set for the given CharID. Will not return null. + * + * Note that this method SHOULD NOT be public. The CacheInfo object is owned + * by LocalSkillCostFacet, and since it can be modified, a reference to + * that object should not be exposed to any object other than + * LocalSkillCostFacet. + * + * @param id + * The CharID for which the CacheInfo should be returned + * @return The CacheInfo for the Player Character represented by the given + * CharID. + */ + private CacheInfo getConstructingInfo(CharID id) + { + CacheInfo rci = getInfo(id); + if (rci == null) + { + rci = new CacheInfo(); + FacetCache.set(id, thisClass, rci); + } + return rci; + } + + /** + * Returns the type-safe CacheInfo for this LocalSkillCostFacet and the + * given CharID. May return null if no Skill information has been set for + * the given CharID. + * + * Note that this method SHOULD NOT be public. The CacheInfo object is owned + * by LocalSkillCostFacet, and since it can be modified, a reference to + * that object should not be exposed to any object other than + * LocalSkillCostFacet. + * + * @param id + * The CharID for which the CacheInfo should be returned + * @return The CacheInfo for the Player Character represented by the given + * CharID; null if no Skill information has been set for the Player + * Character. + */ + private CacheInfo getInfo(CharID id) + { + return (CacheInfo) FacetCache.get(id, thisClass); + } + + /** + * CacheInfo is the data structure used by LocalSkillCostFacet to store a + * Player Character's Skill Costs + */ + private static class CacheInfo + { + Map<PCClass, Map<SkillCost, Map<Skill, Set<CDOMObject>>>> map = new IdentityHashMap<PCClass, Map<SkillCost, Map<Skill, Set<CDOMObject>>>>(); + + public void add(PCClass cl, Skill skill, SkillCost sc, CDOMObject source) + { + Map<SkillCost, Map<Skill, Set<CDOMObject>>> scMap = map.get(cl); + if (scMap == null) + { + scMap = new IdentityHashMap<SkillCost, Map<Skill, Set<CDOMObject>>>(); + map.put(cl, scMap); + } + Map<Skill, Set<CDOMObject>> skMap = scMap.get(sc); + if (skMap == null) + { + skMap = new IdentityHashMap<Skill, Set<CDOMObject>>(); + scMap.put(sc, skMap); + } + Set<CDOMObject> set = skMap.get(skill); + if (set == null) + { + set = new WrappedMapSet<CDOMObject>(IdentityHashMap.class); + skMap.put(skill, set); + } + set.add(source); + } + + public void remove(PCClass cl, Skill skill, SkillCost sc, + CDOMObject source) + { + Map<SkillCost, Map<Skill, Set<CDOMObject>>> scMap = map.get(cl); + if (scMap == null) + { + return; + } + Map<Skill, Set<CDOMObject>> skMap = scMap.get(sc); + if (skMap == null) + { + return; + } + Set<CDOMObject> set = skMap.get(skill); + if (set == null) + { + return; + } + if (set.remove(source) && set.isEmpty()) + { + skMap.remove(skill); + if (skMap.isEmpty()) + { + scMap.remove(sc); + if (scMap.isEmpty()) + { + map.remove(cl); + } + } + } + } + + public boolean contains(PCClass cl, SkillCost sc, Skill skill) + { + Map<SkillCost, Map<Skill, Set<CDOMObject>>> scMap = map.get(cl); + if (scMap == null) + { + return false; + } + Map<Skill, Set<CDOMObject>> skMap = scMap.get(sc); + return (skMap != null) && skMap.containsKey(skill); + } + } + + public void add(CharID id, PCClass cl, Skill skill, SkillCost sc, + CDOMObject source) + { + getConstructingInfo(id).add(cl, skill, sc, source); + } + + public void remove(CharID id, PCClass cl, Skill skill, SkillCost sc, + CDOMObject source) + { + CacheInfo info = getInfo(id); + if (info != null) + { + info.remove(cl, skill, sc, source); + } + } + + public boolean contains(CharID id, PCClass cl, Skill skill, SkillCost sc) + { + CacheInfo info = getInfo(id); + return info != null && info.contains(cl, sc, skill); + } + +} Added: Trunk/pcgen/code/src/java/pcgen/cdom/facet/LocalSkillCostFacet.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/cdom/facet/LocalSkillCostFacet.java (rev 0) +++ Trunk/pcgen/code/src/java/pcgen/cdom/facet/LocalSkillCostFacet.java 2010-07-13 22:36:01 UTC (rev 12559) @@ -0,0 +1,293 @@ +/* + * Copyright (c) Thomas Parker, 2010. + * + * This program 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 program 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ +package pcgen.cdom.facet; + +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import pcgen.base.util.WrappedMapSet; +import pcgen.cdom.base.CDOMObject; +import pcgen.cdom.base.CDOMReference; +import pcgen.cdom.enumeration.CharID; +import pcgen.cdom.enumeration.ListKey; +import pcgen.cdom.enumeration.ObjectKey; +import pcgen.cdom.enumeration.SkillCost; +import pcgen.cdom.inst.PCClassLevel; +import pcgen.core.Domain; +import pcgen.core.PCClass; +import pcgen.core.Skill; + +/** + * SkillCostFacet is a Facet to track Skill costs + */ +public class LocalSkillCostFacet implements DataFacetChangeListener<CDOMObject> +{ + private final Class<?> thisClass = getClass(); + + private final DomainFacet domainFacet = FacetLibrary + .getFacet(DomainFacet.class); + + /** + * Triggered when one of the Facets to which ShieldProfFacet listens fires a + * DataFacetChangeEvent to indicate a ShieldProf was added to a Player + * Character. + * + * @param dfce + * The DataFacetChangeEvent containing the information about the + * change + * + * @see pcgen.cdom.facet.DataFacetChangeListener#dataAdded(pcgen.cdom.facet.DataFacetChangeEvent) + */ + public void dataAdded(DataFacetChangeEvent<CDOMObject> dfce) + { + CDOMObject cdo = dfce.getCDOMObject(); + CharID id = dfce.getCharID(); + PCClass owner; + if (cdo instanceof Domain) + { + owner = domainFacet.getSource(id, (Domain) cdo).getPcclass(); + } + else if (cdo instanceof PCClassLevel) + { + owner = (PCClass) cdo.get(ObjectKey.PARENT); + } + else if (cdo instanceof PCClass) + { + owner = (PCClass) cdo; + } + else + { + return; + } + for (CDOMReference<Skill> ref : cdo.getSafeListFor(ListKey.LOCALCSKILL)) + { + for (Skill sk : ref.getContainedObjects()) + { + add(id, owner, sk, SkillCost.CLASS, cdo); + } + } + for (CDOMReference<Skill> ref : cdo.getSafeListFor(ListKey.LOCALCCSKILL)) + { + for (Skill sk : ref.getContainedObjects()) + { + add(id, owner, sk, SkillCost.CROSS_CLASS, cdo); + } + } + } + + /** + * Triggered when one of the Facets to which ShieldProfFacet listens fires a + * DataFacetChangeEvent to indicate a ShieldProf was removed from a Player + * Character. + * + * @param dfce + * The DataFacetChangeEvent containing the information about the + * change + * + * @see pcgen.cdom.facet.DataFacetChangeListener#dataRemoved(pcgen.cdom.facet.DataFacetChangeEvent) + */ + public void dataRemoved(DataFacetChangeEvent<CDOMObject> dfce) + { + removeAll(dfce.getCharID(), dfce.getCDOMObject()); + } + + /** + * Returns the type-safe CacheInfo for this SkillCostFacet and the given + * CharID. Will return a new, empty CacheInfo if no Skill information has + * been set for the given CharID. Will not return null. + * + * Note that this method SHOULD NOT be public. The CacheInfo object is owned + * by SkillCostFacet, and since it can be modified, a reference to that + * object should not be exposed to any object other than SkillCostFacet. + * + * @param id + * The CharID for which the CacheInfo should be returned + * @return The CacheInfo for the Player Character represented by the given + * CharID. + */ + private CacheInfo getConstructingInfo(CharID id) + { + CacheInfo rci = getInfo(id); + if (rci == null) + { + rci = new CacheInfo(); + FacetCache.set(id, thisClass, rci); + } + return rci; + } + + /** + * Returns the type-safe CacheInfo for this SkillCostFacet and the given + * CharID. May return null if no Skill information has been set for the + * given CharID. + * + * Note that this method SHOULD NOT be public. The CacheInfo object is owned + * by SkillCostFacet, and since it can be modified, a reference to that + * object should not be exposed to any object other than SkillCostFacet. + * + * @param id + * The CharID for which the CacheInfo should be returned + * @return The CacheInfo for the Player Character represented by the given + * CharID; null if no Skill information has been set for the Player + * Character. + */ + private CacheInfo getInfo(CharID id) + { + return (CacheInfo) FacetCache.get(id, thisClass); + } + + /** + * CacheInfo is the data structure used by LocalSkillCostFacet to store a + * Player Character's Skill Costs + */ + private static class CacheInfo + { + Map<PCClass, Map<SkillCost, Map<Skill, Set<CDOMObject>>>> map = new IdentityHashMap<PCClass, Map<SkillCost, Map<Skill, Set<CDOMObject>>>>(); + + public void add(PCClass cl, Skill skill, SkillCost sc, CDOMObject source) + { + Map<SkillCost, Map<Skill, Set<CDOMObject>>> scMap = map.get(cl); + if (scMap == null) + { + scMap = new IdentityHashMap<SkillCost, Map<Skill, Set<CDOMObject>>>(); + map.put(cl, scMap); + } + Map<Skill, Set<CDOMObject>> skMap = scMap.get(sc); + if (skMap == null) + { + skMap = new IdentityHashMap<Skill, Set<CDOMObject>>(); + scMap.put(sc, skMap); + } + Set<CDOMObject> set = skMap.get(skill); + if (set == null) + { + set = new WrappedMapSet<CDOMObject>(IdentityHashMap.class); + skMap.put(skill, set); + } + set.add(source); + } + + public void remove(PCClass cl, Skill skill, SkillCost sc, + CDOMObject source) + { + Map<SkillCost, Map<Skill, Set<CDOMObject>>> scMap = map.get(cl); + if (scMap == null) + { + return; + } + Map<Skill, Set<CDOMObject>> skMap = scMap.get(sc); + if (skMap == null) + { + return; + } + Set<CDOMObject> set = skMap.get(skill); + if (set == null) + { + return; + } + if (set.remove(source) && set.isEmpty()) + { + skMap.remove(skill); + if (skMap.isEmpty()) + { + scMap.remove(sc); + if (scMap.isEmpty()) + { + map.remove(cl); + } + } + } + } + + public void removeAll(Object source) + { + for (Iterator<Map<SkillCost, Map<Skill, Set<CDOMObject>>>> clValues = map + .values().iterator(); clValues.hasNext();) + { + Map<SkillCost, Map<Skill, Set<CDOMObject>>> scMap = clValues + .next(); + for (Iterator<Map<Skill, Set<CDOMObject>>> scValues = scMap + .values().iterator(); scValues.hasNext();) + { + Map<Skill, Set<CDOMObject>> skMap = scValues.next(); + for (Iterator<Set<CDOMObject>> skValues = skMap.values() + .iterator(); skValues.hasNext();) + { + Set<CDOMObject> set = skValues.next(); + if (set.remove(source) && set.isEmpty()) + { + skValues.remove(); + } + } + if (skMap.isEmpty()) + { + scValues.remove(); + } + } + if (scMap.isEmpty()) + { + clValues.remove(); + } + } + } + + public boolean contains(PCClass cl, SkillCost sc, Skill skill) + { + Map<SkillCost, Map<Skill, Set<CDOMObject>>> scMap = map.get(cl); + if (scMap == null) + { + return false; + } + Map<Skill, Set<CDOMObject>> skMap = scMap.get(sc); + return (skMap != null) && skMap.containsKey(skill); + } + } + + public void add(CharID id, PCClass cl, Skill skill, SkillCost sc, + CDOMObject source) + { + getConstructingInfo(id).add(cl, skill, sc, source); + } + + public void remove(CharID id, PCClass cl, Skill skill, SkillCost sc, + CDOMObject source) + { + CacheInfo info = getInfo(id); + if (info != null) + { + info.remove(cl, skill, sc, source); + } + } + + public void removeAll(CharID id, CDOMObject source) + { + CacheInfo ci = getInfo(id); + if (ci != null) + { + ci.removeAll(source); + } + } + + public boolean contains(CharID id, PCClass cl, SkillCost sc, Skill sk) + { + CacheInfo ci = getInfo(id); + return ci != null && ci.contains(cl, sc, sk); + } +} Modified: Trunk/pcgen/code/src/java/pcgen/cdom/helper/ClassSkillChoiceActor.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/cdom/helper/ClassSkillChoiceActor.java 2010-07-13 21:56:04 UTC (rev 12558) +++ Trunk/pcgen/code/src/java/pcgen/cdom/helper/ClassSkillChoiceActor.java 2010-07-13 22:36:01 UTC (rev 12559) @@ -22,7 +22,7 @@ import pcgen.cdom.base.CDOMObject; import pcgen.cdom.base.PersistentChoiceActor; -import pcgen.cdom.enumeration.AssociationListKey; +import pcgen.cdom.enumeration.SkillCost; import pcgen.core.Globals; import pcgen.core.PCClass; import pcgen.core.PlayerCharacter; @@ -89,7 +89,7 @@ { pc.addSkill(choice); PCClass pcc = pc.getClassKeyed(source.getKeyName()); - pc.addAssoc(pcc, AssociationListKey.CSKILL, choice); + pc.addLocalCost(pcc, choice, SkillCost.CLASS, owner); if (applyRank != null) { SkillRankControl.modRanks(applyRank, pcc, false, pc, choice); @@ -174,7 +174,7 @@ { pc.addSkill(choice); PCClass pcc = pc.getClassKeyed(source.getKeyName()); - pc.addAssoc(pcc, AssociationListKey.CSKILL, choice); + pc.addLocalCost(pcc, choice, SkillCost.CLASS, owner); } /** @@ -208,7 +208,7 @@ { SkillRankControl.modRanks(-applyRank, pcc, false, pc, choice); } - pc.removeAssoc(pcc, AssociationListKey.CSKILL, choice); + pc.removeLocalCost(pcc, choice, SkillCost.CLASS, owner); } /** Modified: Trunk/pcgen/code/src/java/pcgen/core/PCClass.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/core/PCClass.java 2010-07-13 21:56:04 UTC (rev 12558) +++ Trunk/pcgen/code/src/java/pcgen/core/PCClass.java 2010-07-13 22:36:01 UTC (rev 12559) @@ -1639,11 +1639,11 @@ .getListFor(ListKey.CSKILL)); } - if (otherClass.containsListFor(ListKey.CCSKILL)) + if (otherClass.containsListFor(ListKey.LOCALCCSKILL)) { - removeListFor(ListKey.CCSKILL); - addAllToListFor(ListKey.CCSKILL, otherClass - .getListFor(ListKey.CCSKILL)); + removeListFor(ListKey.LOCALCCSKILL); + addAllToListFor(ListKey.LOCALCCSKILL, otherClass + .getListFor(ListKey.LOCALCCSKILL)); } removeListFor(ListKey.KIT_CHOICE); Modified: Trunk/pcgen/code/src/java/pcgen/core/PlayerCharacter.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/core/PlayerCharacter.java 2010-07-13 21:56:04 UTC (rev 12558) +++ Trunk/pcgen/code/src/java/pcgen/core/PlayerCharacter.java 2010-07-13 22:36:01 UTC (rev 12559) @@ -142,6 +142,8 @@ import pcgen.cdom.facet.LevelFacet; import pcgen.cdom.facet.LevelTableFacet; import pcgen.cdom.facet.LoadFacet; +import pcgen.cdom.facet.LocalAddedSkillCostFacet; +import pcgen.cdom.facet.LocalSkillCostFacet; import pcgen.cdom.facet.MasterFacet; import pcgen.cdom.facet.MoneyFacet; import pcgen.cdom.facet.MonsterCSkillFacet; @@ -345,6 +347,8 @@ private AddedBonusFacet addedBonusFacet = FacetLibrary.getFacet(AddedBonusFacet.class); private GlobalAddedSkillCostFacet globalAddedSkillCostFacet = FacetLibrary.getFacet(GlobalAddedSkillCostFacet.class); private GlobalSkillCostFacet globalSkillCostFacet = FacetLibrary.getFacet(GlobalSkillCostFacet.class); + private LocalAddedSkillCostFacet localAddedSkillCostFacet = FacetLibrary.getFacet(LocalAddedSkillCostFacet.class); + private LocalSkillCostFacet localSkillCostFacet = FacetLibrary.getFacet(LocalSkillCostFacet.class); private FormulaResolvingFacet resolveFacet = FacetLibrary.getFacet(FormulaResolvingFacet.class); private PrerequisiteFacet prereqFacet = FacetLibrary.getFacet(PrerequisiteFacet.class); @@ -13444,4 +13448,21 @@ || globalAddedSkillCostFacet.contains(id, skill, sc); } + public void addLocalCost(PCClass pcc, Skill skill, SkillCost sc, + CDOMObject owner) + { + localAddedSkillCostFacet.add(id, pcc, skill, sc, owner); + } + + public void removeLocalCost(PCClass pcc, Skill skill, SkillCost sc, + CDOMObject owner) + { + localAddedSkillCostFacet.remove(id, pcc, skill, sc, owner); + } + + public boolean hasLocalCost(PCClass cl, Skill skill, SkillCost sc) + { + return localSkillCostFacet.contains(id, cl, sc, skill) + || localAddedSkillCostFacet.contains(id, cl, skill, sc); + } } Modified: Trunk/pcgen/code/src/java/pcgen/core/analysis/SkillCostCalc.java =================================================================== --- Trunk/pcgen/code/src/java/pcgen/core/analysis/SkillCostCalc.java 2010-07-13 21:56:04 UTC (rev 12558) +++ Trunk/pcgen/code/src/java/pcgen/core/analysis/SkillCostCalc.java 2010-07-13 22:36:01 UTC (rev 12559) @@ -25,23 +25,14 @@ import java.util.List; import pcgen.cdom.base.AssociatedPrereqObject; -import pcgen.cdom.base.CDOMObject; import pcgen.cdom.base.CDOMReference; import pcgen.cdom.base.MasterListInterface; import pcgen.cdom.enumeration.AssociationKey; -import pcgen.cdom.enumeration.AssociationListKey; -import pcgen.cdom.enumeration.ListKey; import pcgen.cdom.enumeration.ObjectKey; import pcgen.cdom.enumeration.SkillCost; -import pcgen.cdom.inst.PCClassLevel; import pcgen.cdom.list.ClassSkillList; -import pcgen.core.Ability; -import pcgen.core.Domain; -import pcgen.core.Equipment; -import pcgen.core.EquipmentModifier; import pcgen.core.Globals; import pcgen.core.PCClass; -import pcgen.core.PCTemplate; import pcgen.core.PlayerCharacter; import pcgen.core.Race; import pcgen.core.Skill; @@ -62,21 +53,11 @@ return true; } - // hasSkill is a LevelAbility skill - if (hasClassSkill(aPC, aClass, sk)) + if (aPC.hasLocalCost(aClass, sk, SkillCost.CLASS)) { return true; } - for (int i = 1; i <= aPC.getLevel(aClass); i++) - { - PCClassLevel classLevel = aPC.getActiveClassLevel(aClass, i); - if (SkillCostCalc.hasParentCSkill(aPC, classLevel, sk)) - { - return true; - } - } - // test for SKILLLIST skill if (aClass.hasClassSkill(aPC, sk)) { @@ -91,16 +72,6 @@ } } - for (Domain d : aPC.getDomainSet()) - { - if (aClass.getKeyName().equals( - aPC.getDomainSource(d).getPcclass().getKeyName()) - && SkillCostCalc.hasParentCSkill(aPC, d, sk)) - { - return true; - } - } - List<ClassSkillList> skillLists = ClassSkillApplication .getClassSkillList(aPC, aClass); if (hasMasterSkill(skillLists, sk)) @@ -110,14 +81,6 @@ return false; } - private static boolean hasClassSkill(PlayerCharacter pc, PCClass cl, - Skill sk) - { - List<Skill> assocCSkill = pc - .getAssocList(cl, AssociationListKey.CSKILL); - return assocCSkill != null && assocCSkill.contains(sk); - } - public static boolean hasMasterSkill(List<ClassSkillList> skillLists, Skill sk) { MasterListInterface masterLists = Globals.getMasterLists(); @@ -175,40 +138,16 @@ return false; } - if (SkillCostCalc.hasCcSkill(aPC, aPC.getRace(), sk)) + if (aPC.hasGlobalCost(sk, SkillCost.CROSS_CLASS)) { return true; } - for (Domain d : aPC.getDomainSet()) + if (aPC.hasLocalCost(aClass, sk, SkillCost.CROSS_CLASS)) { - if (aClass.getKeyName().equals( - aPC.getDomainSource(d).getPcclass().getKeyName()) - && SkillCostCalc.hasCcSkill(aPC, d, sk)) - { - return true; - } - } - - if ((aPC.getDeity() != null) && SkillCostCalc.hasCcSkill(aPC, aPC.getDeity(), sk)) - { return true; } - if (SkillCostCalc.hasCcSkill(aPC, aClass, sk)) - { - return true; - } - - for (int i = 1; i <= aPC.getLevel(aClass); i++) - { - PCClassLevel classLevel = aPC.getActiveClassLevel(aClass, i); - if (SkillCostCalc.hasCcSkill(aPC, classLevel, sk)) - { - return true; - } - } - if (aClass.isMonster()) { if (hasMonsterCCSkill(aPC.getRace(), sk)) @@ -217,54 +156,6 @@ } } - for (Ability feat : aPC.getFullAbilitySet()) - { - if (SkillCostCalc.hasCcSkill(aPC, feat, sk)) - { - return true; - } - } - - for (Skill aSkill : aPC.getSkillSet()) - { - if (SkillCostCalc.hasCcSkill(aPC, aSkill, sk)) - { - return true; - } - } - - for (Equipment eq : aPC.getEquippedEquipmentSet()) - { - if (SkillCostCalc.hasCcSkill(aPC, eq, sk)) - { - return true; - } - - for (EquipmentModifier eqMod : eq.getEqModifierList(true)) - { - if (SkillCostCalc.hasCcSkill(aPC, eqMod, sk)) - { - return true; - } - } - - for (EquipmentModifier eqMod : eq.getEqModifierList(false)) - { - if (SkillCostCalc.hasCcSkill(aPC, eqMod, sk)) - { - return true; - } - } - } - - for (PCTemplate template : aPC.getTemplateSet()) - { - if (SkillCostCalc.hasCcSkill(aPC, template, sk)) - { - return true; - } - } - return false; } @@ -321,54 +212,4 @@ } return false; } - - public static boolean hasCcSkill(PlayerCharacter pc, CDOMObject po, Skill skill) - { - List<CDOMReference<Skill>> ccSkillList = po.getListFor(ListKey.CCSKILL); - List<Skill> assocCCSkill = pc.getAssocList(po, - AssociationListKey.CCSKILL); - if (ccSkillList != null && !ccSkillList.isEmpty()) - { - for (CDOMReference<Skill> ref : ccSkillList) - { - if (ref.contains(skill)) - { - return true; - } - } - } - if (assocCCSkill != null && !assocCCSkill.isEmpty()) - { - if (assocCCSkill.contains(skill)) - { - return true; - } - } - return false; - } - - public static boolean hasParentCSkill(PlayerCharacter pc, CDOMObject po, Skill skill) - { - List<CDOMReference<Skill>> cSkillList = po.getListFor(ListKey.PARENTCSKILL); - if (cSkillList != null) - { - for (CDOMReference<Skill> ref : cSkillList) - { - if (ref.contains(skill)) - { - return true; - } - } - } - List<Skill> assocCSkill = pc.getAssocList(po, AssociationListKey.PARENTCSKILL); - if (assocCSkill != null) - { - if (assocCSkill.contains(skill)) - { - return true; - } - } - return false; - } - } Modified: Trunk/pcgen/code/src/java/plugin/lsttokens/CcskillLst.java =================================================================== --- Trunk/pcgen/code/src/java/plugin/lsttokens/CcskillLst.java 2010-07-13 21:56:04 UTC (rev 12558) +++ Trunk/pcgen/code/src/java/plugin/lsttokens/CcskillLst.java 2010-07-13 22:36:01 UTC (rev 12559) @@ -26,8 +26,8 @@ import pcgen.cdom.base.CDOMReference; import pcgen.cdom.base.ChooseResultActor; import pcgen.cdom.base.Constants; -import pcgen.cdom.enumeration.AssociationListKey; import pcgen.cdom.enumeration.ListKey; +import pcgen.cdom.enumeration.SkillCost; import pcgen.cdom.reference.PatternMatchingReference; import pcgen.cdom.reference.ReferenceUtilities; import pcgen.core.Globals; @@ -250,7 +250,7 @@ .silentlyGetConstructedCDOMObject(SKILL_CLASS, o); if (skill != null) { - pc.addAssoc(obj, AssociationListKey.CCSKILL, skill); + pc.addGlobalCost(SkillCost.CROSS_CLASS, skill, obj); } } @@ -260,7 +260,7 @@ .silentlyGetConstructedCDOMObject(SKILL_CLASS, o); if (skill != null) { - pc.removeAssoc(obj, AssociationListKey.CCSKILL, skill); + pc.removeGlobalCost(SkillCost.CROSS_CLASS, skill, obj); } } Added: Trunk/pcgen/code/src/java/plugin/lsttokens/domain/CcskillToken.java =================================================================== --- Trunk/pcgen/code/src/java/plugin/lsttokens/domain/CcskillToken.java (rev 0) +++ Trunk/pcgen/code/src/java/plugin/lsttokens/domain/CcskillToken.java 2010-07-13 22:36:01 UTC (rev 12559) @@ -0,0 +1,283 @@ +/* + * Copyright 2008 (C) Thomas Parker <th...@us...> + * + * 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 + */ +package plugin.lsttokens.domain; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.StringTokenizer; + +import pcgen.cdom.base.CDOMObject; +import pcgen.cdom.base.CDOMReference; +import pcgen.cdom.base.ChooseResultActor; +import pcgen.cdom.base.Constants; +import pcgen.cdom.enumeration.ListKey; +import pcgen.cdom.enumeration.SkillCost; +import pcgen.cdom.reference.PatternMatchingReference; +import pcgen.cdom.reference.ReferenceUtilities; +import pcgen.core.Domain; +import pcgen.core.Globals; +import pcgen.core.PCClass; +import pcgen.core.PlayerCharacter; +import pcgen.core.Skill; +import pcgen.persistence.PersistenceLayerException; +import pcgen.rules.context.Changes; +import pcgen.rules.context.LoadContext; +import pcgen.rules.persistence.TokenUtilities; +import pcgen.rules.persistence.token.AbstractTokenWithSeparator; +import pcgen.rules.persistence.token.CDOMPrimaryParserToken; +import pcgen.rules.persistence.token.ParseResult; + +/** + * @author djones4 + * + */ +public class CcskillToken extends AbstractTokenWithSeparator<Domain> implements + CDOMPrimaryParserToken<Domain>, ChooseResultActor +{ + + private static final Class<Skill> SKILL_CLASS = Skill.class; + + @Override + public String getTokenName() + { + return "CCSKILL"; + } + + @Override + protected char separator() + { + return '|'; + } + + @Override + protected ParseResult parseTokenWithSeparator(LoadContext context, + Domain obj, String value) + { + boolean first = true; + boolean foundAny = false; + boolean foundOther = false; + + StringTokenizer tok = new StringTokenizer(value, Constants.PIPE); + while (tok.hasMoreTokens()) + { + String tokText = tok.nextToken(); + if (Constants.LST_DOT_CLEAR.equals(tokText)) + { + if (!first) + { + return new ParseResult.Fail(" Non-sensical " + + getTokenName() + + ": .CLEAR was not the first list item"); + } + context.getObjectContext().removeList(obj, + ListKey.LOCALCCSKILL); + } + else if (tokText.startsWith(Constants.LST_DOT_CLEAR_DOT)) + { + String clearText = tokText.substring(7); + if (Constants.LST_ALL.equals(clearText)) + { + context.getObjectContext().removeFromList(obj, + ListKey.LOCALCCSKILL, + context.ref.getCDOMAllReference(SKILL_CLASS)); + } + else if (Constants.LST_LIST.equals(clearText)) + { + context.getObjectContext().removeFromList(obj, + ListKey.CHOOSE_ACTOR, this); + } + else + { + CDOMReference<Skill> ref = TokenUtilities + .getTypeOrPrimitive(context, SKILL_CLASS, clearText); + if (ref == null) + { + return new ParseResult.Fail( + " Error was encountered while parsing " + + getTokenName()); + } + context.getObjectContext().removeFromList(obj, + ListKey.LOCALCCSKILL, ref); + } + } + else + { + /* + * Note this HAS to be done one-by-one, because the + * .clearChildNodeOfClass method above does NOT recognize the + * C/CC Skill object and therefore doesn't know how to search + * the sublists + */ + if (Constants.LST_ALL.equals(tokText)) + { + foundAny = true; + context.getObjectContext().addToList(obj, + ListKey.LOCALCCSKILL, + context.ref.getCDOMAllReference(SKILL_CLASS)); + } + else + { + foundOther = true; + if (Constants.LST_LIST.equals(tokText)) + { + context.getObjectContext().addToList(obj, + ListKey.CHOOSE_ACTOR, this); + } + else + { + CDOMReference<Skill> ref = getSkillReference(context, + tokText); + if (ref == null) + { + return new ParseResult.Fail( + " Error was encountered while parsing " + + getTokenName()); + } + context.getObjectContext().addToList(obj, + ListKey.LOCALCCSKILL, ref); + } + } + } + first = false; + } + if (foundAny && foundOther) + { + return new ParseResult.Fail("Non-sensical " + getTokenName() + + ": Contains ANY and a specific reference: " + value); + } + return ParseResult.SUCCESS; + } + + private CDOMReference<Skill> getSkillReference(LoadContext context, + String tokText) + { + if (tokText.endsWith(Constants.LST_PATTERN)) + { + return new PatternMatchingReference<Skill>(Skill.class, context.ref + .getCDOMAllReference(SKILL_CLASS), tokText); + } + else + { + return TokenUtilities.getTypeOrPrimitive(context, SKILL_CLASS, + tokText); + } + } + + public String[] unparse(LoadContext context, Domain obj) + { + Changes<CDOMReference<Skill>> changes = context.getObjectContext() + .getListChanges(obj, ListKey.LOCALCCSKILL); + Changes<ChooseResultActor> listChanges = context.getObjectContext() + .getListChanges(obj, ListKey.CHOOSE_ACTOR); + List<String> list = new ArrayList<String>(); + Collection<CDOMReference<Skill>> removedItems = changes.getRemoved(); + if (removedItems != null && !removedItems.isEmpty()) + { + if (changes.includesGlobalClear()) + { + context.addWriteMessage("Non-sensical relationship in " + + getTokenName() + + ": global .CLEAR and local .CLEAR. performed"); + return null; + } + list.add(Constants.LST_DOT_CLEAR_DOT + + ReferenceUtilities + .joinLstFormat(removedItems, "|.CLEAR.")); + } + Collection<ChooseResultActor> listRemoved = listChanges.getRemoved(); + if (listRemoved != null && !listRemoved.isEmpty()) + { + if (listRemoved.contains(this)) + { + list.add(".CLEAR.LIST"); + } + } + if (changes.includesGlobalClear()) + { + list.add(Constants.LST_DOT_CLEAR); + } + Collection<CDOMReference<Skill>> added = changes.getAdded(); + if (added != null && !added.isEmpty()) + { + list.add(ReferenceUtilities.joinLstFormat(added, Constants.PIPE)); + } + Collection<ChooseResultActor> listAdded = listChanges.getAdded(); + if (listAdded != null && !listAdded.isEmpty()) + { + for (ChooseResultActor cra : listAdded) + { + if (cra.getSource().equals(getTokenName())) + { + try + { + list.add(cra.getLstFormat()); + } + catch (PersistenceLayerException e) + { + context.addWriteMessage("Error writing Prerequisite: " + + e); + return null; + } + } + } + } + if (list.isEmpty()) + { + return null; + } + return list.toArray(new String[list.size()]); + } + + public Class<Domain> getTokenClass() + { + return Domain.class; + } + + public void apply(PlayerCharacter pc, CDOMObject obj, String o) + { + Skill skill = Globals.getContext().ref + .silentlyGetConstructedCDOMObject(SKILL_CLASS, o); + if (skill != null) + { + PCClass pcc = pc.getDomainSource((Domain) obj).getPcclass(); + pc.addLocalCost(pcc, skill, SkillCost.CROSS_CLASS, obj); + } + } + + public void remove(PlayerCharacter pc, CDOMObject obj, String o) + { + Skill skill = Globals.getContext().ref + .silentlyGetConstructedCDOMObject(SKILL_CLASS, o); + if (skill != null) + { + PCClass pcc = pc.getDomainSource((Domain) obj).getPcclass(); + pc.removeLocalCost(pcc, skill, SkillCost.CROSS_CLASS, obj); + } + } + + public String getSource() + { + return getTokenName(); + } + + public String getLstFormat() + { + return "LIST"; + } +} Modified: Trunk/pcgen/code/src/java/plugin/lsttokens/domain/CskillToken.java =================================================================== --- Trunk/pcgen/code/src/java/plugin/lsttokens/domain/CskillToken.java 2010-07-13 21:56:04 UTC (rev 12558) +++ Trunk/pcgen/code/src/java/plugin/lsttokens/domain/CskillToken.java 2010-07-13 22:36:01 UTC (rev 12559) @@ -26,12 +26,13 @@ import pcgen.cdom.base.CDOMReference; import pcgen.cdom.base.ChooseResultActor; import pcgen.cdom.base.Constants; -import pcgen.cdom.enumeration.AssociationListKey; import pcgen.cdom.enumeration.ListKey; +import pcgen.cdom.enumeration.SkillCost; import pcgen.cdom.reference.PatternMatchingReference; import pcgen.cdom.reference.ReferenceUtilities; import pcgen.core.Domain; import pcgen.core.Globals; +import pcgen.core.PCClass; import pcgen.core.PlayerCharacter; import pcgen.core.Skill; import pcgen.persistence.PersistenceLayerException; @@ -44,7 +45,7 @@ /** * @author djones4 - * + * */ public class CskillToken extends AbstractTokenWithSeparator<Domain> implements CDOMPrimaryParserToken<Domain>, ChooseResultActor @@ -83,7 +84,8 @@ + getTokenName() + ": .CLEAR was not the first list item"); } - context.getObjectContext().removeList(obj, ListKey.PARENTCSKILL); + context.getObjectContext() + .removeList(obj, ListKey.LOCALCSKILL); } else if (tokText.startsWith(Constants.LST_DOT_CLEAR_DOT)) { @@ -91,7 +93,7 @@ if (Constants.LST_ALL.equals(clearText)) { context.getObjectContext().removeFromList(obj, - ListKey.PARENTCSKILL, + ListKey.LOCALCSKILL, context.ref.getCDOMAllReference(SKILL_CLASS)); } else if (Constants.LST_LIST.equals(clearText)) @@ -110,7 +112,7 @@ + getTokenName()); } context.getObjectContext().removeFromList(obj, - ListKey.PARENTCSKILL, ref); + ListKey.LOCALCSKILL, ref); } } else @@ -124,7 +126,8 @@ if (Constants.LST_ALL.equals(tokText)) { foundAny = true; - context.getObjectContext().addToList(obj, ListKey.PARENTCSKILL, + context.getObjectContext().addToList(obj, + ListKey.LOCALCSKILL, context.ref.getCDOMAllReference(SKILL_CLASS)); } else @@ -141,11 +144,12 @@ tokText); if (ref == null) { - return new ParseResult.Fail(" Error was encountered while parsing " + return new ParseResult.Fail( + " Error was encountered while parsing " + getTokenName()); } context.getObjectContext().addToList(obj, - ListKey.PARENTCSKILL, ref); + ListKey.LOCALCSKILL, ref); } } } @@ -177,7 +181,7 @@ public String[] unparse(LoadContext context, Domain obj) { Changes<CDOMReference<Skill>> changes = context.getObjectContext() - .getListChanges(obj, ListKey.PARENTCSKILL); + .getListChanges(obj, ListKey.LOCALCSKILL); Changes<ChooseResultActor> listChanges = context.getObjectContext() .getListChanges(obj, ListKey.CHOOSE_ACTOR); List<String> list = new ArrayList<String>(); @@ -250,7 +254,8 @@ .silentlyGetConstructedCDOMObject(SKILL_CLASS, o); if (skill != null) { - pc.addAssoc(obj, AssociationListKey.PARENTCSKILL, skill); + PCClass pcc = pc.getDomainSource((Domain) obj).getPcclass(); + pc.addLocalCost(pcc, skill, SkillCost.CLASS, obj); } } @@ -260,7 +265,8 @@ .silentlyGetConstructedCDOMObject(SKILL_CLASS, o); if (skill != null) { - pc.removeAssoc(obj, AssociationListKey.PARENTCSKILL, skill); + PCClass pcc = pc.getDomainSource((Domain) obj).getPcclass(); + pc.removeLocalCost(pcc, skill, SkillCost.CLASS, obj); } } Added: Trunk/pcgen/code/src/java/plugin/lsttokens/pcclass/CcskillToken.java =================================================================== --- Trunk/pcgen/code/src/java/plugin/lsttokens/pcclass/CcskillToken.java (rev 0) +++ Trunk/pcgen/code/src/java/plugin/lsttokens/pcclass/CcskillToken.java 2010-07-13 22:36:01 UTC (rev 12559) @@ -0,0 +1,205 @@ +/* + * Copyright 2008 (C) Thomas Parker <th...@us...> + * + * 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 + */ +package plugin.lsttokens.pcclass; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.StringTokenizer; + +import pcgen.cdom.base.CDOMReference; +import pcgen.cdom.base.Constants; +import pcgen.cdom.enumeration.ListKey; +import pcgen.cdom.reference.PatternMatchingReference; +import pcgen.cdom.reference.ReferenceUtilities; +import pcgen.core.PCClass; +import pcgen.core.Skill; +import pcgen.rules.context.Changes; +import pcgen.rules.context.LoadContext; +import pcgen.rules.persistence.TokenUtilities; +import pcgen.rules.persistence.token.AbstractTokenWithSeparator; +import pcgen.rules.persistence.token.CDOMPrimaryParserToken; +import pcgen.rules.persistence.token.ParseResult; + +/** + * @author djones4 + * + */ +public class CcskillToken extends AbstractTokenWithSeparator<PCClass> implements + CDOMPrimaryParserToken<PCClass> +{ + + private static final Class<Skill> SKILL_CLASS = Skill.class; + + @Override + public String getTokenName() + { + return "CCSKILL"; + } + + @Override + protected char separator() + { + return '|'; + } + + @Override + protected ParseResult parseTokenWithSeparator(LoadContext context, + PCClass obj, String value) + { + boolean first = true; + boolean foundAny = false; + boolean foundOther = false; + + StringTokenizer tok = new StringTokenizer(value, Constants.PIPE); + while (tok.hasMoreTokens()) + { + String tokText = tok.nextToken(); + if (Constants.LST_DOT_CLEAR.equals(tokText)) + { + if (!first) + { + return new ParseResult.Fail(" Non-sensical " + + getTokenName() + + ": .CLEAR was not the first list item"); + } + context.getObjectContext().removeList(obj, ListKey.LOCALCCSKILL); + } + else if (tokText.startsWith(Constants.LST_DOT_CLEAR_DOT)) + { + String clearText = tokText.substring(7); + if (Constants.LST_ALL.equals(clearText)) + { + context.getObjectContext().removeFromList(obj, + ListKey.LOCALCCSKILL, + context.ref.getCDOMAllReference(SKILL_CLASS)); + } + else + { + CDOMReference<Skill> ref = TokenUtilities + .getTypeOrPrimitive(context, SKILL_CLASS, clearText); + if (ref == null) + { + return new ParseResult.Fail( + " Error was encountered while parsing " + + getTokenName()); + } + context.getObjectContext().removeFromList(obj, + ListKey.LOCALCCSKILL, ref); + } + } + else + { + /* + * Note this HAS to be done one-by-one, because the + * .clearChildNodeOfClass method above does NOT recognize the + * C/CC Skill object and therefore doesn't know how to search + * the sublists + */ + if (Constants.LST_ALL.equals(tokText)) + { + foundAny = true; + context.getObjectContext().addToList(obj, + ListKey.LOCALCCSKILL, + context.ref.getCDOMAllReference(SKILL_CLASS)); + } + else + { + foundOther = true; + CDOMReference<Skill> ref = getSkillReference(context, + tokText); + if (ref == null) + { + return new ParseResult.Fail( + " Error was encountered while parsing " + + getTokenName()); + } + context.getObjectContext().addToList(obj, + ListKey.LOCALCCSKILL, ref); + } + } + first = false; + } + if (foundAny && foundOther) + { + return new ParseResult.Fail("Non-sensical " + getTokenName() + + ": Contains ANY and a specific reference: " + value); + } + return ParseResult.SUCCESS; + } + + private CDOMReference<Skill> getSkillReference(LoadContext context, + String tokText) + { + if (tokText.endsWith(Constants.LST_PATTERN)) + { + return new PatternMatchingReference<Skill>(Skill.class, context.ref + .getCDOMAllReference(SKILL_CLASS), tokText); + } + else + { + return TokenUtilities.getTypeOrPrimitive(context, SKILL_CLASS, + tokText); + } + } + + public String[] unparse(LoadContext context, PCClass obj) + { + Changes<CDOMReference<Skill>> changes = context.getObjectContext() + .getListChanges(obj, ListKey.LOCALCCSKILL); + List<String> list = new ArrayList<String>(); + Collection<CDOMReference<Skill>> removedItems = changes.getRemoved(); + if (removedItems != null && !removedItems.isEmpty()) + { + if (changes.includesGlobalClear()) + { + context.addWriteMessage("Non-sensical relationship in " + + getTokenName() + + ": global .CLEAR and local .CLEAR. performed"); + return null; + } + list.add(Constants.LST_DOT_CLEAR_DOT + + ReferenceUtilities + .joinLstFormat(removedItems, "|.CLEAR.")); + } + if (changes.includesGlobalClear()) + { + list.add(Constants.LST_DOT_CLEAR); + } + Collection<CDOMReference<Skill>> added = changes.getAdded(); + if (added != null && !added.isEmpty()) + { + list.add(ReferenceUtilities.joinLstFormat(added, Constants.PIPE)); + } + if (list.isEmpty()) + { + return null; + } + return list.toArray(new String[list.size()]); + } + + public Class<PCClass> getTokenClass() + { + return PCClass.class; + } + + public String getSource() + { + return getTokenName(); + } +} Added: Trunk/pcgen/code/src/java/plugin/lsttokens/pcclass/level/CcskillToken.java =================================================================== --- Trunk/pcgen/code/src/java/plugin/lsttokens/pcclass/level/CcskillToken.java (rev 0) +++ Trunk/pcgen/code/src/java/plugin/lsttokens/pcclass/level/CcskillToken.java 2010-07-13 22:36:01 UTC (rev 12559) @@ -0,0 +1,206 @@ +/* + * Copyright 2008 (C) Thomas Parker <th...@us...> + * + * 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 + */ +package plugin.lsttokens.pcclass.level; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.StringTokenizer; + +import pcgen.cdom.base.CDOMReference; +import pcgen.cdom.base.Constants; +import pcgen.cdom.enumeration.ListKey; +import pcgen.cdom.inst.PCClassLevel; +import pcgen.cdom.reference.PatternMatchingReference; +import pcgen.cdom.reference.ReferenceUtilities; +import pcgen.core.Skill; +import pcgen.rules.context.Changes; +import pcgen.rules.context.LoadContext; +import pcgen.rules.persistence.TokenUtilities; +import pcgen.rules.persistence.token.AbstractTokenWithSeparator; +import pcgen.rules.persistence.token.CDOMPrimaryParserToken; +import pcgen.rules.persistence.token.ParseResult; + +/** + * @author djones4 + * + */ +public class CcskillToken extends AbstractTokenWithSeparator<PCClassLevel> + implements CDOMPrimaryParserToken<PCClassLevel> +{ + + private static final Class<Skill> SKILL_CLASS = Skill.class; + + @Override + public String getTokenName() + { + return "CCSKILL"; + } + + @Override + protected char separator() + { + return '|'; + } + + @Override + protected ParseResult parseTokenWithSeparator(LoadContext context, + PCClassLevel obj, String value) + { + boolean first = true; + boolean foundAny = false; + boolean foundOther = false; + + StringTokenizer tok = new StringTokenizer(value, Constants.PIPE); + while (tok.hasMoreTokens()) + { + String tokText = tok.nextToken(); + if (Constants.LST_DOT_CLEAR.equals(tokText)) + { + if (!first) + { + return new ParseResult.Fail(" Non-sensical " + + getTokenName() + + ": .CLEAR was not the first list item"); + } + context.getObjectContext().removeList(obj, + ListKey.LOCALCCSKILL); + } + else if (tokText.startsWith(Constants.LST_DOT_CLEAR_DOT)) + { + String clearText = tokText.substring(7); + if (Constants.LST_ALL.equals(clearText)) + { + context.getObjectContext().removeFromList(obj, + ListKey.LOCALCCSKILL, + context.ref.getCDOMAllReference(SKILL_CLASS)); + } + else + { + CDOMReference<Skill> ref = TokenUtilities + .getTypeOrPrimitive(context, SKILL_CLASS, clearText); + if (ref == null) + { + return new ParseResult.Fail( + " Error was encountered while parsing " + + getTokenName()); + } + context.getObjectContext().removeFromList(obj, + ListKey.LOCALCCSKILL, ref); + } + } + else + { + /* + * Note this HAS to be done one-by-one, because the + * .clearChildNodeOfClass method above does NOT recognize the + * C/CC Skill object and therefore doesn't know how to search + * the sublists + */ + if (Constants.LST_ALL.equals(tokText)) + { + foundAny = true; + context.getObjectContext().addToList(obj, + ListKey.LOCALCCSKILL, + context.ref.getCDOMAllReference(SKILL_CLASS)); + } + else + { + foundOther = true; + CDOMReference<Skill> ref = getSkillReference(context, + tokText); + if (ref == null) + { + return new ParseResult.Fail( + " Error was encountered while parsing " + + getTokenName()); + } + context.getObjectContext().addToList(obj, + ListKey.LOCALCCSKILL, ref); + } + } + first = false; + } + if (foundAny && foundOther) + { + return new ParseResult.Fail("Non-sensical " + getTokenName() + + ": Contains ANY and a specific reference: " + value); + } + return ParseResult.SUCCESS; + } + + private CDOMReference<Skill> getSkillReference(LoadContext context, + String tokText) + { + if (tokText.endsWith(Constants.LST_PATTERN)) + { + return new PatternMatchingReference<Skill>(Skill.class, context.ref + .getCDOMAllReference(SKILL_CLASS), tokText); + } + else + { + return TokenUtilities.getTypeOrPrimitive(context, SKILL_CLASS, + tokText); + } + } + + public String[] unparse(LoadContext context, PCClassLevel obj) + { + Changes<CDOMReference<Skill>> changes = context.getObjectContext() + .getListChanges(obj, ListKey.LOCALCCSKILL); + List<String> list = new ArrayList<String>(); + Collection<CDOMReference<Skill>> removedItems = changes.getRemoved(); + if (removedItems != null && !removedItems.isEmpty()) + { + if (changes.includesGlobalClear()) + { + context.addWriteMessage("Non-sensical relationship in " + + getTokenName() + + ": global .CLEAR and local .CLEAR. performed"); + return null; + } + list.add(Constants.LST_DOT_CLEAR_DOT + + ReferenceUtilities + .joinLstFormat(removedItems, "|.CLEAR.")); + } + if (changes.includesGlobalClear()) + { + list.add(Constants.LST_DOT_CLEAR); + } + Collection<CDOMReference<Skill>> added = changes.getAdded(); + if (added != null && !added.isEmpty()) + { + list.add(ReferenceUtilities.joinLstFormat(added, Constants.PIPE)); + } + if (list.isEmpty()) + { + return null; + } + return list.toArray(new String[list.size()]); + } + + public Class<PCClassLevel> getTokenClass() + { + return PCClassLevel.class; + } + + public String getSource() + { + return getTokenName(); + } +} Modified: Trunk/pcgen/code/src/java/plugin/lsttokens/pcclass/level/CskillToken.java =================================================================== --- Trunk/pcgen/code/src/java/plugin/lsttokens/pcclass/level/CskillToken.java 2010-07-13 21:56:04 UTC (rev 12558) +++ Trunk/pcgen/code/src/java/plugin/lsttokens/pcclass/level/CskillToken.java 2010-07-13 22:36:01 UTC (rev 12559) @@ -78,7 +78,7 @@ + ": .CLEAR was not the first list item"); } context.getObjectContext() - .removeList(obj, ListKey.PARENTCSKILL); + .removeList(obj, ListKey.LOCALCSKILL); } else if (tokText.startsWith(Constants.LST_DOT_CLEAR_DOT)) { @@ -86,7 +86,7 @@ if (Constants.LST_ALL.equals(clearText)) { context.getObjectContext().removeFromList(obj, - ListKey.PARENTCSKILL, + ListKey.LOCALCSKILL, context.ref.getCDOMAllReference(SKILL_CLASS)); } else @@ -100,7 +100,7 @@ + getTokenName()); } context.getObjectContext().removeFromList(obj, - ListKey.PARENTCSKILL, ref); + ListKey.LOCALCSKILL, ref); } } else @@ -115,7 +115,7 @@ { foundAny = true; context.getObjectContext().addToList(obj, - ListKey.PARENTCSKILL, + ListKey.LOCALCSKILL, context.ref.getCDOMAllReference(SKILL_CLASS)); } else @@ -130,7 +130,7 @@ + getTokenName()); } context.getObjectContext().addToList(obj, - ListKey.PARENTCSKILL, ref); + ListKey.LOCALCSKILL, ref); } } first = false; @@ -161,7 +161,7 @@ public String[] unparse(LoadContext context, PCClassLevel obj) { Changes<CDOMReference<Skill>> changes = context.getObjectContext() - .getListChanges(obj, ListKey.PARENTCSKILL); + .getListChanges(obj, ListKey.LOCALCSKILL); List<String> list = new ArrayList<String>(); Collection<CDOMReference<Skill>> removedItems = changes.getRemoved(); if (removedItems != null && !removedItems.isEmpty()) Modified: Trunk/pcgen/code/src/test/pcgen/core/prereq/PreCSkillTest.java =================================================================== --- Trunk/pcgen/code/src/test/pcgen/core/prereq/PreCSkillTest.java 2010-07-13 21:56:04 UTC (rev 12558) +++ Trunk/pcgen/code/src/test/pcgen/core/prereq/PreCSkillTest.java 2010-07-13 22:36:01 UTC (rev 12559) @@ -26,9 +26,9 @@ import junit.textui.TestRunner; import pcgen.AbstractCharacterTestCase; import pcgen.cdom.base.FormulaFactor... [truncated message content] |