public static PersistentTransitionChoice<?> processOldAdd(LoadContext context, String first) throws PersistenceLayerException { int openParenLoc = first.indexOf('('); if (openParenLoc == -1) { Logging.errorPrint("Expected to have a ( : " + first); return null; } int closeParenLoc = first.lastIndexOf(')'); if (openParenLoc == -1) { Logging.errorPrint("Expected to have a ) : " + first); return null; } String key = first.substring(7, openParenLoc); String choices = first.substring(openParenLoc + 1, closeParenLoc); String count = ""; if (closeParenLoc != first.length() - 1) { count = first.substring(closeParenLoc + 1) + '|'; } PCClass applied = new PCClass(); ParseResult pr = context.processSubToken(applied, "ADD", key, count + choices); pr.printMessages(); if (!pr.passed()) { return null; } context.commit(); PersistentTransitionChoice<?> ptc = applied.getListFor(ListKey.ADD).get(0); return ptc; }
/** * Remove a domain from the character. * * @param pc The character * @param domain The domain. */ public static void removeDomain(PlayerCharacter pc, Domain domain) { ClassSource source = pc.getDomainSource(domain); PCClass aClass = pc.getClassKeyed(source.getPcclass().getKeyName()); if (aClass != null) { int maxLevel; for (maxLevel = 0; maxLevel < 10; maxLevel++) { if (pc.getSpellSupport(aClass).getCastForLevel(maxLevel, pc) == 0) { break; } } if (maxLevel > 0) { removeSpellsFromClassForLevels(pc, domain, aClass); } if ((maxLevel > 1) && (aClass.getSafe(IntegerKey.KNOWN_SPELLS_FROM_SPECIALTY) == 0)) { DomainSpellList domainSpellList = domain.get(ObjectKey.DOMAIN_SPELLLIST); final List<Spell> aList = pc.getAllSpellsInLists(Collections.singletonList(domainSpellList)); for (Spell gcs : aList) { if (SpellLevel.getFirstLvlForKey(gcs, domainSpellList, pc) < maxLevel) { pc.removeDomainSpellCount(aClass); break; } } } } if (!pc.isImporting()) { BonusActivation.deactivateBonuses(domain, pc); } }
@Override protected void setUp() throws Exception { super.setUp(); lscFacet = FacetLibrary.getFacet(ListSkillCostFacet.class); sk = context.ref.constructCDOMObject(Skill.class, "MySkill"); dragon = context.ref.constructCDOMObject(PCClass.class, "Dragon"); dragon.addToListFor(ListKey.TYPE, Type.MONSTER); dragon.put(ObjectKey.IS_MONSTER, Boolean.TRUE); TokenRegistration.register(CHOOSE_SKILL_TOKEN); ChooserFactory.setDelegate(new MockUIDelegate()); }
/** * Sets the locked flag on a PC * * @param pc */ public static void applyDomain(PlayerCharacter pc, Domain d) { ClassSource source = pc.getDomainSource(d); PCClass aClass = pc.getClassKeyed(source.getPcclass().getKeyName()); if (aClass != null) { int maxLevel; for (maxLevel = 0; maxLevel < 10; maxLevel++) { if (pc.getSpellSupport(aClass).getCastForLevel(maxLevel, pc) == 0) { break; } } if (maxLevel > 0) { addSpellsToClassForLevels(pc, d, aClass, 0, maxLevel - 1); } if ((maxLevel > 1) && (aClass.getSafe(IntegerKey.KNOWN_SPELLS_FROM_SPECIALTY) == 0)) { DomainSpellList domainSpellList = d.get(ObjectKey.DOMAIN_SPELLLIST); final List<Spell> aList = pc.getAllSpellsInLists(Collections.singletonList(domainSpellList)); for (Spell gcs : aList) { if (SpellLevel.getFirstLvlForKey(gcs, domainSpellList, pc) < maxLevel) { pc.setDomainSpellCount(aClass, 1); break; } } } } Collection<CDOMReference<Spell>> mods = d.getSafeListMods(Spell.SPELLS); for (CDOMReference<Spell> ref : mods) { Collection<Spell> spells = ref.getContainedObjects(); Collection<AssociatedPrereqObject> assoc = d.getListAssociations(Spell.SPELLS, ref); for (AssociatedPrereqObject apo : assoc) { if (!PrereqHandler.passesAll(apo.getPrerequisiteList(), pc, d)) { continue; } for (Spell s : spells) { String book = apo.getAssociation(AssociationKey.SPELLBOOK); List<CharacterSpell> aList = pc.getCharacterSpells(aClass, s, book, -1); if (aList.isEmpty()) { Formula times = apo.getAssociation(AssociationKey.TIMES_PER_UNIT); CharacterSpell cs = new CharacterSpell(d, s); int resolvedTimes = times.resolve(pc, d.getQualifiedKey()).intValue(); cs.addInfo(1, resolvedTimes, book); pc.addCharacterSpell(aClass, cs); } } } } }
private List<PCClass> getCharactersSpellcastingClasses() { List<PCClass> castingClasses = new ArrayList<>(); Collection<PCClass> classes = charDisplay.getClassSet(); for (PCClass pcClass : classes) { if (pcClass.get(FactKey.valueOf("SpellType")) != null) { SpellSupportForPCClass spellSupport = pc.getSpellSupport(pcClass); if (spellSupport.canCastSpells(pc) || spellSupport.hasKnownList()) { castingClasses.add(pcClass); } } } return castingClasses; }
/** * Test to ensure that a character will fail a test if it does not have the correct number of * levels in the class. * * @throws Exception */ public void testCharWithMultipleSpellClasses() throws Exception { LoadContext context = Globals.getContext(); final PCClass pcClass = new PCClass(); pcClass.setName("MyClass"); context.unconditionallyProcess(pcClass, "SPELLSTAT", "CHA"); pcClass.put(StringKey.SPELLTYPE, "ARCANE"); context.unconditionallyProcess(pcClass.getOriginalClassLevel(1), "CAST", "5,4"); final PCClass pcClass2 = new PCClass(); pcClass2.setName("Other Class"); context.unconditionallyProcess(pcClass2, "SPELLSTAT", "INT"); pcClass2.put(StringKey.SPELLTYPE, "ARCANE"); context.unconditionallyProcess(pcClass2.getOriginalClassLevel(1), "CAST", "5,4"); final PlayerCharacter character = getCharacter(); setPCStat(character, cha, 12); setPCStat(character, intel, 12); character.incrementClassLevel(1, pcClass); character.incrementClassLevel(2, pcClass2); final PreClassParser producer = new PreClassParser(); final Prerequisite prereq = producer.parse("CLASS", "1,SPELLCASTER.Arcane,SPELLCASTER.Arcane=2", false, false); final PreMult test = new PreMult(); final int passes = test.passes(prereq, character, null); assertEquals(1, passes); }
public int getLevelApplied(PCClass cl) { int result = -1; Map<CDOMSingleRef<? extends PCClass>, Integer> ac = getMapFor(MapKey.APPLIED_CLASS); if (ac != null) { for (Map.Entry<CDOMSingleRef<? extends PCClass>, Integer> me : ac.entrySet()) { PCClass pcclass = me.getKey().get(); if (pcclass.getKeyName().equalsIgnoreCase(cl.getKeyName())) { result = me.getValue(); } } } return result; }
/* * @see TestCase#setUp() */ @Override protected void setUp() throws Exception { super.setUp(); LoadContext context = Globals.getContext(); SettingsHandler.getGame().setSpellBaseDC("10+SPELLLEVEL+BASESPELLSTAT"); SimpleLoader<BonusSpellInfo> bonusSpellLoader = new SimpleLoader<BonusSpellInfo>(BonusSpellInfo.class); try { URI testURI = new URI("file:/" + getClass().getName() + ".java"); bonusSpellLoader.parseLine(context, "1 BASESTATSCORE:12 STATRANGE:8", testURI); bonusSpellLoader.parseLine(context, "2 BASESTATSCORE:14 STATRANGE:8", testURI); bonusSpellLoader.parseLine(context, "3 BASESTATSCORE:16 STATRANGE:8", testURI); } catch (URISyntaxException e) { throw new UnreachableError(e); } // Human human = new Race(); final BonusObj bon = Bonus.newBonus(context, "FEAT|POOL|2"); human.addToListFor(ListKey.BONUS, bon); arcaneClass = new PCClass(); arcaneClass.setName("TestArcane"); arcaneClass.put(StringKey.SPELLTYPE, "ARCANE"); context.unconditionallyProcess(arcaneClass, "SPELLSTAT", "CHA"); arcaneClass.put(ObjectKey.SPELLBOOK, false); arcaneClass.put(ObjectKey.MEMORIZE_SPELLS, false); context.unconditionallyProcess(arcaneClass.getOriginalClassLevel(1), "KNOWN", "4,2,1"); context.unconditionallyProcess(arcaneClass.getOriginalClassLevel(1), "CAST", "3,1,0"); context.getReferenceContext().importObject(arcaneClass); divineClass = new PCClass(); divineClass.setName("TestDivine"); divineClass.put(StringKey.SPELLTYPE, "DIVINE"); context.unconditionallyProcess(divineClass, "SPELLSTAT", "WIS"); divineClass.put(ObjectKey.SPELLBOOK, false); divineClass.put(ObjectKey.MEMORIZE_SPELLS, true); context.unconditionallyProcess(divineClass.getOriginalClassLevel(1), "CAST", "3,1,0"); context.unconditionallyProcess( divineClass, "SPELLLEVEL", "CLASS|SPELLCASTER.Divine=1|Cure Light Wounds"); context.getReferenceContext().importObject(divineClass); context.resolveDeferredTokens(); context.getReferenceContext().buildDerivedObjects(); context.getReferenceContext().resolveReferences(null); }
public static void addDomainsUpToLevel(PCClass cl, final int aLevel, final PlayerCharacter aPC) { // any domains set by level would have already been saved // and don't need to be re-set at level up time if (aPC.isImporting()) { return; } /* * Note this uses ALL of the domains up to and including this level, * because there is the possibility (albeit strange) that the PC was not * qualified at a previous level change, but the PlayerCharacter is now * qualified for the given Domain. Even this has quirks, since it is * only applied at the time of level increase, but I think that quirk * should be resolved by a CDOM system around 6.0 - thpr 10/23/06 */ for (QualifiedObject<CDOMSingleRef<Domain>> qo : cl.getSafeListFor(ListKey.DOMAIN)) { CDOMSingleRef<Domain> ref = qo.getObject(aPC, cl); if (ref != null) { addDomain(aPC, cl, ref.resolvesTo()); } } for (int i = 0; i <= aLevel; i++) { // TODO This stinks for really high level characters - can this ever // get null back? PCClassLevel pcl = aPC.getActiveClassLevel(cl, i); for (QualifiedObject<CDOMSingleRef<Domain>> qo : pcl.getSafeListFor(ListKey.DOMAIN)) { CDOMSingleRef<Domain> ref = qo.getObject(aPC, cl); if (ref != null) { addDomain(aPC, cl, ref.resolvesTo()); } } } }
public static void removeDomainsForLevel( PCClass cl, final int removedLevel, final PlayerCharacter aPC) { /* * Note this uses ALL of the domains up to and including this level, * because there is the possibility (albeit strange) that the PC was * qualified at a previous level change, but the PlayerCharacter is now * not qualified for the given Domain. Even this has quirks, since it is * only applied at the time of level increase, but I think that quirk * should be resolved by a CDOM system around 6.0 - thpr 10/23/06 */ for (QualifiedObject<CDOMSingleRef<Domain>> qo : cl.getSafeListFor(ListKey.DOMAIN)) { CDOMSingleRef<Domain> ref = qo.getObject(aPC, cl); if (ref == null) { ref = qo.getRawObject(); aPC.removeDomain(ref.resolvesTo()); } } for (int i = 0; i <= removedLevel; i++) { // TODO This stinks for really high level characters - can this ever // get null back? PCClassLevel pcl = aPC.getActiveClassLevel(cl, i); for (QualifiedObject<CDOMSingleRef<Domain>> qo : pcl.getSafeListFor(ListKey.DOMAIN)) { CDOMSingleRef<Domain> ref = qo.getObject(aPC, cl); if ((ref == null) || (i == removedLevel)) { ref = qo.getRawObject(); aPC.removeDomain(ref.resolvesTo()); } } } }
private void initializeObjects() { s1 = new Skill(); s1.setName("s1"); primaryContext.getReferenceContext().importObject(s1); s2 = new Skill(); s2.setName("s2"); primaryContext.getReferenceContext().importObject(s2); primaryContext.unconditionallyProcess(s2, "TYPE", "Masterful"); s3 = new Skill(); s3.setName("s3"); primaryContext.getReferenceContext().importObject(s3); primaryContext.unconditionallyProcess(s3, "TYPE", "Masterful"); s4 = new Skill(); s4.setName("s4"); s4.put(ObjectKey.EXCLUSIVE, Boolean.TRUE); primaryContext.unconditionallyProcess(s4, "TYPE", "Masterful"); primaryContext.getReferenceContext().importObject(s4); s5 = new Skill(); s5.setName("s5"); s5.put(ObjectKey.EXCLUSIVE, Boolean.TRUE); primaryContext.getReferenceContext().importObject(s5); cl1 = new PCClass(); cl1.setName("MyClass"); primaryContext.getReferenceContext().importObject(cl1); }
/** * Create a map of the spell nodes for a class in the supplied list. This is intended to allow * quick checking of the presence of a spell in the list. * * @param spellNodeList The list of spell nodes * @param pcClass The class to filter the map by * @return A double map to the class' spells from the list. */ private DoubleKeyMapToList<SpellFacade, String, SpellNode> buildExistingSpellMap( DefaultListFacade<SpellNode> spellNodeList, PCClass pcClass) { DoubleKeyMapToList<SpellFacade, String, SpellNode> spellMap = new DoubleKeyMapToList<>(); for (SpellNode spellNode : spellNodeList) { if (pcClass.equals(spellNode.getSpellcastingClass())) { spellMap.addToListFor(spellNode.getSpell(), spellNode.getSpellLevel(), spellNode); } } return spellMap; }
@Override public PCClass clone() { PCClass aClass = null; try { aClass = (PCClass) super.clone(); List<KnownSpellIdentifier> ksl = getListFor(ListKey.KNOWN_SPELLS); if (ksl != null) { aClass.removeListFor(ListKey.KNOWN_SPELLS); for (KnownSpellIdentifier ksi : ksl) { aClass.addToListFor(ListKey.KNOWN_SPELLS, ksi); } } Map<AttackType, Integer> acmap = getMapFor(MapKey.ATTACK_CYCLE); if (acmap != null && !acmap.isEmpty()) { aClass.removeMapFor(MapKey.ATTACK_CYCLE); for (Map.Entry<AttackType, Integer> me : acmap.entrySet()) { aClass.addToMapFor(MapKey.ATTACK_CYCLE, me.getKey(), me.getValue()); } } aClass.levelMap = new TreeMap<>(); for (Map.Entry<Integer, PCClassLevel> me : levelMap.entrySet()) { aClass.levelMap.put(me.getKey(), me.getValue().clone()); } } catch (CloneNotSupportedException exc) { ShowMessageDelegate.showMessageDialog( exc.getMessage(), Constants.APPLICATION_NAME, MessageType.ERROR); } return aClass; }
@Override public ParseResult parseToken(LoadContext context, PCClassLevel obj, String value) { if (ONE.equals(obj.get(IntegerKey.LEVEL))) { PCClass parent = (PCClass) obj.get(ObjectKey.TOKEN_PARENT); if (parent instanceof SubClass || parent instanceof SubstitutionClass) { return new ParseResult.Fail( "Data used token: " + value + " which is a Class token, " + "but it was used in a class level for a " + parent.getClass().getSimpleName(), context); } return wrappedToken.parseToken(context, parent, value); } return new ParseResult.Fail( "Data used token: " + value + " which is a Class token, " + "but it was used in a class level line other than level 1", context); }
/** * Needs documentation. * * @param pc update skills for this PC * @param aSkill Skill to update * @param aRank Number of ranks to add * @param aCost Cost of added ranks * @param langList Languages to be selected for a language skill * @param pcClass skills apply to this class * @return <code>true</code> for success TODO What about throwing on failure? */ private boolean updatePCSkills( final PlayerCharacter pc, final Skill aSkill, final int aRank, final double aCost, List<Language> langList, final PCClass pcClass) { pc.addSkill(aSkill); boolean oldImporting = pc.isImporting(); pc.setImporting(true); final String aString = SkillRankControl.modRanks(aRank, pcClass, true, pc, aSkill); pc.setImporting(oldImporting); if (aString.length() > 0) { Logging.errorPrint("SKILL: " + aString); return false; } // Add any supplied languages ChoiceManagerList<Language> controller = ChooserUtilities.getConfiguredController(aSkill, pc, null, new ArrayList<String>()); for (Language lang : langList) { if (!controller.conditionallyApply(pc, lang)) { Logging.errorPrint("Failed to apply Language into Skill: " + lang.getLSTformat()); } } // // Fix up the skill pools to reflect what we just spent. // double ptsToSpend = aCost; if (ptsToSpend >= 0.0) { for (PCLevelInfo info : pc.getLevelInfo()) { if (info.getClassKeyName().equals(pcClass.getKeyName())) { // We are spending this class' points. int remaining = info.getSkillPointsRemaining(); if (remaining == 0) { continue; } int left = remaining - (int) Math.min(remaining, ptsToSpend); info.setSkillPointsRemaining(left); ptsToSpend -= (remaining - left); if (ptsToSpend <= 0) { break; } } } } return true; }
/** * @see pcgen.io.exporttoken.Token#getToken(java.lang.String, pcgen.core.PlayerCharacter, * pcgen.io.ExportHandler) */ @Override public String getToken(String tokenSource, PlayerCharacter pc, ExportHandler eh) { StringBuffer retValue = new StringBuffer(); SpellListTokenParams params = new SpellListTokenParams(tokenSource, SpellListToken.SPELLTAG_MEMORIZE); final CDOMObject aObject = pc.getSpellClassAtIndex(params.getClassNum()); if (aObject != null) { PCClass aClass = null; if (aObject instanceof PCClass) { aClass = (PCClass) aObject; } if (aClass != null) { retValue.append((boolean) aClass.getSafe(ObjectKey.MEMORIZE_SPELLS)); } } return retValue.toString(); }
/* (non-Javadoc) * @see pcgen.core.facade.SpellSupportFacade#addSpellList(java.lang.String) */ @Override public void addSpellList(String spellList) { if (StringUtils.isEmpty(spellList)) { return; } // Prevent spellbooks being given the same name as a class for (PCClass current : Globals.getContext().getReferenceContext().getConstructedCDOMObjects(PCClass.class)) { if ((spellList.equals(current.getKeyName()))) { JOptionPane.showMessageDialog( null, LanguageBundle.getString("in_spellbook_name_error"), // $NON-NLS-1$ Constants.APPLICATION_NAME, JOptionPane.ERROR_MESSAGE); return; } } if (pc.addSpellBook(spellList)) { pc.setDirty(true); DummySpellNodeImpl spellListNode = new DummySpellNodeImpl(getRootNode(spellList)); preparedSpellLists.add(spellListNode); addDummyNodeIfSpellListEmpty(spellList); } else { JOptionPane.showMessageDialog( null, LanguageBundle.getFormattedString( "InfoPreparedSpells.add.list.fail", spellList), // $NON-NLS-1$ Constants.APPLICATION_NAME, JOptionPane.ERROR_MESSAGE); return; } }
public static String getRanksExplanation(PlayerCharacter pc, Skill sk) { StringBuilder sb = new StringBuilder(100); boolean needComma = false; for (PCClass pcc : pc.getSkillRankClasses(sk)) { if (needComma) { sb.append(", "); } sb.append(pcc == null ? "None" : pcc.getKeyName()); sb.append(':'); Double rank = pc.getSkillRankForClass(sk, pcc); sb.append(rank == null ? 0 : rank); needComma = true; } double bonus = SkillRankControl.getSkillRankBonusTo(pc, sk); if (bonus != 0d) { if (sb.length() > 0) { sb.append("; "); } sb.append("Skillrank bonus "); sb.append(NumberFormat.getNumberInstance().format(bonus)); } return sb.toString(); }
/* (non-Javadoc) * @see junit.framework.TestCase#setUp() */ @Override protected void setUp() throws Exception { super.setUp(); final PlayerCharacter character = getCharacter(); myClass = new PCClass(); myClass.setName("My Class"); knowledge = new Skill(); Globals.getContext().unconditionallyProcess(knowledge, "CLASSES", "My Class"); knowledge.setName("KNOWLEDGE (ARCANA)"); TestHelper.addType(knowledge, "KNOWLEDGE.INT"); character.addSkill(knowledge); SkillRankControl.modRanks(8.0, myClass, true, character, knowledge); }
/* * CONSIDER Why does this not inherit classSkillChoices? */ public void inheritAttributesFrom(final PCClass otherClass) { Boolean hbss = otherClass.get(ObjectKey.HAS_BONUS_SPELL_STAT); if (hbss != null) { put(ObjectKey.HAS_BONUS_SPELL_STAT, hbss); CDOMSingleRef<PCStat> bss = otherClass.get(ObjectKey.BONUS_SPELL_STAT); if (bss != null) { put(ObjectKey.BONUS_SPELL_STAT, bss); } } Boolean usbs = otherClass.get(ObjectKey.USE_SPELL_SPELL_STAT); if (usbs != null) { put(ObjectKey.USE_SPELL_SPELL_STAT, usbs); } Boolean cwss = otherClass.get(ObjectKey.CASTER_WITHOUT_SPELL_STAT); if (cwss != null) { put(ObjectKey.CASTER_WITHOUT_SPELL_STAT, cwss); } CDOMSingleRef<PCStat> ss = otherClass.get(ObjectKey.SPELL_STAT); if (ss != null) { put(ObjectKey.SPELL_STAT, ss); } TransitionChoice<CDOMListObject<Spell>> slc = otherClass.get(ObjectKey.SPELLLIST_CHOICE); if (slc != null) { put(ObjectKey.SPELLLIST_CHOICE, slc); } List<QualifiedObject<CDOMReference<Equipment>>> e = otherClass.getListFor(ListKey.EQUIPMENT); if (e != null) { addAllToListFor(ListKey.EQUIPMENT, e); } List<WeaponProfProvider> wp = otherClass.getListFor(ListKey.WEAPONPROF); if (wp != null) { addAllToListFor(ListKey.WEAPONPROF, wp); } QualifiedObject<Boolean> otherWP = otherClass.get(ObjectKey.HAS_DEITY_WEAPONPROF); if (otherWP != null) { put(ObjectKey.HAS_DEITY_WEAPONPROF, otherWP); } List<ArmorProfProvider> ap = otherClass.getListFor(ListKey.AUTO_ARMORPROF); if (ap != null) { addAllToListFor(ListKey.AUTO_ARMORPROF, ap); } List<ShieldProfProvider> sp = otherClass.getListFor(ListKey.AUTO_SHIELDPROF); if (sp != null) { addAllToListFor(ListKey.AUTO_SHIELDPROF, sp); } List<BonusObj> bonusList = otherClass.getListFor(ListKey.BONUS); if (bonusList != null) { addAllToListFor(ListKey.BONUS, bonusList); } try { ownBonuses(this); } catch (CloneNotSupportedException ce) { // TODO Auto-generated catch block ce.printStackTrace(); } for (VariableKey vk : otherClass.getVariableKeys()) { put(vk, otherClass.get(vk)); } if (otherClass.containsListFor(ListKey.CSKILL)) { removeListFor(ListKey.CSKILL); addAllToListFor(ListKey.CSKILL, otherClass.getListFor(ListKey.CSKILL)); } if (otherClass.containsListFor(ListKey.LOCALCCSKILL)) { removeListFor(ListKey.LOCALCCSKILL); addAllToListFor(ListKey.LOCALCCSKILL, otherClass.getListFor(ListKey.LOCALCCSKILL)); } removeListFor(ListKey.KIT_CHOICE); addAllToListFor(ListKey.KIT_CHOICE, otherClass.getSafeListFor(ListKey.KIT_CHOICE)); remove(ObjectKey.REGION_CHOICE); if (otherClass.containsKey(ObjectKey.REGION_CHOICE)) { put(ObjectKey.REGION_CHOICE, otherClass.get(ObjectKey.REGION_CHOICE)); } removeListFor(ListKey.SAB); addAllToListFor(ListKey.SAB, otherClass.getSafeListFor(ListKey.SAB)); /* * TODO Does this need to have things from the Class Level objects? * I don't think so based on deferred processing of levels... */ addAllToListFor(ListKey.DAMAGE_REDUCTION, otherClass.getListFor(ListKey.DAMAGE_REDUCTION)); for (CDOMReference<Vision> ref : otherClass.getSafeListMods(Vision.VISIONLIST)) { for (AssociatedPrereqObject apo : otherClass.getListAssociations(Vision.VISIONLIST, ref)) { putToList(Vision.VISIONLIST, ref, apo); } } /* * TODO This is a clone problem, but works for now - thpr 10/3/08 */ if (otherClass instanceof SubClass) { levelMap.clear(); copyLevelsFrom(otherClass); } addAllToListFor(ListKey.NATURAL_WEAPON, otherClass.getListFor(ListKey.NATURAL_WEAPON)); put(ObjectKey.LEVEL_HITDIE, otherClass.get(ObjectKey.LEVEL_HITDIE)); }
/* (non-Javadoc) * @see pcgen.core.facade.SpellSupportFacade#getClassInfo(pcgen.core.facade.ClassFacade) */ @Override public String getClassInfo(ClassFacade spellcaster) { if (!(spellcaster instanceof PCClass)) { return ""; } PCClass aClass = (PCClass) spellcaster; SpellSupportForPCClass spellSupport = pc.getSpellSupport(aClass); int highestSpellLevel = spellSupport.getHighestLevelSpell(pc); final HtmlInfoBuilder b = new HtmlInfoBuilder(); b.append("<table border=1><tr><td><font size=-2><b>"); // $NON-NLS-1$ b.append(OutputNameFormatting.piString(aClass, false)).append(" ["); // $NON-NLS-1$ b.append( String.valueOf( charDisplay.getLevel(aClass) + (int) pc.getTotalBonusTo("PCLEVEL", aClass.getKeyName()))); // $NON-NLS-1$ b.append("]</b></font></td>"); // $NON-NLS-1$ for (int i = 0; i <= highestSpellLevel; ++i) { b.append("<td><font size=-2><b><center> "); // $NON-NLS-1$ b.append(String.valueOf(i)); b.append(" </b></center></font></td>"); // $NON-NLS-1$ } b.append("</tr>"); // $NON-NLS-1$ b.append("<tr><td><font size=-1><b>Cast</b></font></td>"); // $NON-NLS-1$ for (int i = 0; i <= highestSpellLevel; ++i) { b.append("<td><font size=-1><center>"); // $NON-NLS-1$ b.append(getNumCast(aClass, i, pc)); b.append("</center></font></td>"); // $NON-NLS-1$ } b.append("</tr>"); // $NON-NLS-1$ // Making sure KnownList can be handled safely and produces the correct behaviour if (spellSupport.hasKnownList() || spellSupport.hasKnownSpells(pc)) { b.append("<tr><td><font size=-1><b>Known</b></font></td>"); // $NON-NLS-1$ for (int i = 0; i <= highestSpellLevel; ++i) { final int a = spellSupport.getKnownForLevel(i, pc); final int bonus = spellSupport.getSpecialtyKnownForLevel(i, pc); b.append("<td><font size=-1><center>"); // $NON-NLS-1$ b.append(String.valueOf(a)); if (bonus > 0) { b.append('+').append(Integer.toString(bonus)); } b.append("</center></font></td>"); // $NON-NLS-1$ } b.append("</tr>"); // $NON-NLS-1$ } b.append("<tr><td><font size=-1><b>DC</b></font></td>"); // $NON-NLS-1$ for (int i = 0; i <= highestSpellLevel; ++i) { b.append("<td><font size=-1><center>"); // $NON-NLS-1$ b.append(String.valueOf(getDC(aClass, i, pc))); b.append("</center></font></td>"); // $NON-NLS-1$ } b.append("</tr></table>"); // $NON-NLS-1$ b.appendI18nElement("InfoSpells.caster.type", aClass.getSpellType()); // $NON-NLS-1$ b.appendLineBreak(); b.appendI18nElement("InfoSpells.stat.bonus", aClass.getSpellBaseStat()); // $NON-NLS-1$ if (pc.hasAssocs(aClass, AssociationKey.SPECIALTY) || charDisplay.hasDomains()) { boolean needComma = false; StringBuilder schoolInfo = new StringBuilder(); String spec = pc.getAssoc(aClass, AssociationKey.SPECIALTY); if (spec != null) { schoolInfo.append(spec); needComma = true; } for (Domain d : charDisplay.getSortedDomainSet()) { if (needComma) { schoolInfo.append(','); } needComma = true; schoolInfo.append(d.getKeyName()); } b.appendLineBreak(); b.appendI18nElement("InfoSpells.school", schoolInfo.toString()); // $NON-NLS-1$ } Set<String> set = new TreeSet<>(); for (SpellProhibitor sp : aClass.getSafeListFor(ListKey.PROHIBITED_SPELLS)) { set.addAll(sp.getValueList()); } Collection<? extends SpellProhibitor> prohibList = charDisplay.getProhibitedSchools(aClass); if (prohibList != null) { for (SpellProhibitor sp : prohibList) { set.addAll(sp.getValueList()); } } if (!set.isEmpty()) { b.appendLineBreak(); b.appendI18nElement( "InfoSpells.prohibited.school", //$NON-NLS-1$ StringUtil.join(set, ",")); // $NON-NLS-1$ } String bString = SourceFormat.getFormattedString(aClass, Globals.getSourceDisplay(), true); if (bString.length() > 0) { b.appendLineBreak(); b.appendI18nElement("in_source", bString); // $NON-NLS-1$ } return b.toString(); }
public double getMultiClassXPMultiplier(CharID id) { HashSet<PCClass> unfavoredClasses = new HashSet<PCClass>(); SortedSet<PCClass> favored = new TreeSet<PCClass>(CDOMObjectUtilities.CDOM_SORTER); favored.addAll(favoredClassFacet.getSet(id)); SortedSet<PCClass> aList = favored; boolean hasAny = hasAnyFavoredClassFacet.contains(id, Boolean.TRUE); PCClass maxClass = null; PCClass secondClass = null; int maxClassLevel = 0; int secondClassLevel = 0; int xpPenalty = 0; double xpMultiplier = 1.0; for (PCClass pcClass : classFacet.getClassSet(id)) { if (!pcClass.hasXPPenalty()) { continue; } String subClassKey = subClassFacet.getSource(id, pcClass); PCClass evalClass = pcClass; if (subClassKey != null && !subClassKey.equals("None")) { evalClass = pcClass.getSubClassKeyed(subClassKey); } if (!aList.contains(evalClass)) { unfavoredClasses.add(pcClass); int pcClassLevel = classFacet.getLevel(id, pcClass); if (pcClassLevel > maxClassLevel) { if (hasAny) { secondClassLevel = maxClassLevel; secondClass = maxClass; } maxClassLevel = pcClassLevel; maxClass = pcClass; } else if ((pcClassLevel > secondClassLevel) && (hasAny)) { secondClassLevel = pcClassLevel; secondClass = pcClass; } } } if ((hasAny) && (secondClassLevel > 0)) { maxClassLevel = secondClassLevel; unfavoredClasses.remove(maxClass); maxClass = secondClass; } if (maxClassLevel > 0) { unfavoredClasses.remove(maxClass); for (PCClass aClass : unfavoredClasses) { if ((maxClassLevel - (classFacet.getLevel(id, aClass))) > 1) { ++xpPenalty; } } xpMultiplier = 1.0 - (xpPenalty * 0.2); if (xpMultiplier < 0) { xpMultiplier = 0; } } return xpMultiplier; }
private KitSkillAdd addRanks( PlayerCharacter pc, PCClass pcClass, Skill aSkill, double ranksLeftToAdd, boolean isFree, List<String> warnings) { if (!isFree && pcClass.getSkillPool(pc) == 0) { return null; } double curRank = 0.0; if (pc.hasSkill(aSkill)) { curRank = pc.getRank(aSkill).doubleValue(); } double ranksToAdd = ranksLeftToAdd; if (!Globals.checkRule(RuleConstants.SKILLMAX) && (ranksToAdd > 0.0)) { ranksToAdd = Math.min(pc.getMaxRank(aSkill, pcClass).doubleValue(), curRank + ranksLeftToAdd); ranksToAdd -= curRank; if (!CoreUtility.doublesEqual(ranksToAdd, ranksLeftToAdd)) { warnings.add( "SKILL: Could not add " + (ranksLeftToAdd - ranksToAdd) + " to " + aSkill.getDisplayName() + ". Exceeds MAXRANK of " + pc.getMaxRank(aSkill, pcClass) + "."); } } int ptsToSpend = 0; int[] points = new int[pc.getLevelInfoSize()]; if (!isFree) { double ranksAdded = 0.0; int skillCost = pc.getSkillCostForClass(aSkill, pcClass).getCost(); ptsToSpend = (int) (ranksToAdd * skillCost); for (int i = 0; i < pc.getLevelInfoSize(); i++) { PCLevelInfo info = pc.getLevelInfo(i); if (info.getClassKeyName().equals(pcClass.getKeyName())) { // We are spending this class' points. points[i] = info.getSkillPointsRemaining(); } else { points[i] = -1; } } for (int i = 0; i < points.length; i++) { int remaining = points[i]; if (remaining <= 0) { continue; } int left = remaining - Math.min(remaining, ptsToSpend); points[i] = left; int spent = (remaining - left); ptsToSpend -= spent; ranksAdded += ((double) spent / (double) skillCost); if (ranksAdded == ranksToAdd || ptsToSpend <= 0) { break; } } ranksToAdd = ranksAdded; ptsToSpend = (int) (ranksToAdd * skillCost); } pc.addSkill(aSkill); String ret = SkillRankControl.modRanks(ranksToAdd, pcClass, false, pc, aSkill); if (ret.length() > 0) { if (isFree && ret.indexOf("You do not have enough skill points.") != -1) { SkillRankControl.modRanks(ranksToAdd, pcClass, true, pc, aSkill); } else { warnings.add(ret); return null; } } if (!isFree) { for (int i = 0; i < pc.getLevelInfoSize(); i++) { PCLevelInfo info = pc.getLevelInfo(i); if (points[i] >= 0) { info.setSkillPointsRemaining(points[i]); } } } List<Language> langList = new ArrayList<Language>(); if (ChooseActivation.hasChooseToken(aSkill) && !selection.isEmpty()) { ChoiceManagerList<Language> controller = ChooserUtilities.getConfiguredController(aSkill, pc, null, new ArrayList<String>()); int limit = (int) ranksToAdd; for (CDOMSingleRef<Language> ref : selection) { Language lang = ref.resolvesTo(); if (controller.conditionallyApply(pc, lang)) { langList.add(lang); limit--; } if (limit <= 0) { break; } } } return new KitSkillAdd(aSkill, ranksToAdd, ptsToSpend, langList, pcClass); }
private boolean isSpellCaster(PCClass pcc) { return pcc.getSafe(ObjectKey.USE_SPELL_SPELL_STAT) || pcc.getSafe(ObjectKey.CASTER_WITHOUT_SPELL_STAT) || (pcc.get(ObjectKey.SPELL_STAT) != null); }