Search in sources :

Example 1 with BonusSpellInfo

use of pcgen.cdom.content.BonusSpellInfo in project pcgen by PCGen.

the class SpellSupportForPCClass method getCastForLevel.

public int getCastForLevel(int spellLevel, String bookName, boolean includeAdj, boolean limitByStat, PlayerCharacter aPC) {
    int pcLevel = aPC.getLevel(source);
    int total = 0;
    int stat = 0;
    final String classKeyName = "CLASS." + source.getKeyName();
    final String levelSpellLevel = ";LEVEL." + spellLevel;
    final String allSpellLevel = ";LEVEL.All";
    pcLevel += (int) aPC.getTotalBonusTo("PCLEVEL", source.getKeyName());
    pcLevel += (int) aPC.getTotalBonusTo("PCLEVEL", "TYPE." + source.getSpellType());
    if (getNumFromCastList(pcLevel, spellLevel, aPC) < 0) {
        // certain feats
        return (int) aPC.getTotalBonusTo("SPELLCAST", classKeyName + levelSpellLevel);
    }
    total += (int) aPC.getTotalBonusTo("SPELLCAST", classKeyName + levelSpellLevel);
    total += (int) aPC.getTotalBonusTo("SPELLCAST", "TYPE." + source.getSpellType() + levelSpellLevel);
    total += (int) aPC.getTotalBonusTo("SPELLCAST", "CLASS.Any" + levelSpellLevel);
    total += (int) aPC.getTotalBonusTo("SPELLCAST", classKeyName + allSpellLevel);
    total += (int) aPC.getTotalBonusTo("SPELLCAST", "TYPE." + source.getSpellType() + allSpellLevel);
    total += (int) aPC.getTotalBonusTo("SPELLCAST", "CLASS.Any" + allSpellLevel);
    PCStat aStat = source.bonusSpellStat();
    String statString = Constants.NONE;
    if (aStat != null) {
        stat = aPC.getTotalStatFor(aStat);
        statString = aStat.getKeyName();
    }
    final int bonusStat = (int) aPC.getTotalBonusTo("STAT", "CAST." + statString) + (int) aPC.getTotalBonusTo("STAT", "BASESPELLSTAT") + (int) aPC.getTotalBonusTo("STAT", "BASESPELLSTAT;CLASS=" + source.getKeyName());
    if (limitByStat) {
        PCStat ss = source.baseSpellStat();
        if (ss != null) {
            final int maxSpellLevel = aPC.getVariableValue("MAXLEVELSTAT=" + ss.getKeyName(), "").intValue();
            if ((maxSpellLevel + bonusStat) < spellLevel) {
                return total;
            }
        }
    }
    stat += bonusStat;
    // Now we decide whether to adjust the number of slots down
    // the road by adding specialty slots.
    // Reworked to consider the fact that a lower-level
    // specialty spell can go into this level of specialty slot
    //
    int adj = 0;
    if (includeAdj && !bookName.equals(Globals.getDefaultSpellBook()) && (aPC.hasAssocs(source, AssociationKey.SPECIALTY) || aPC.hasDomains())) {
        // we might wind up using THIS level's slots for them.
        for (int ix = 0; ix <= spellLevel; ++ix) {
            Collection<CharacterSpell> aList = aPC.getCharacterSpells(source, ix);
            Collection<Spell> bList = new ArrayList<>();
            if (!aList.isEmpty()) {
                // getNumFromCastList above would have returned -1
                if ((ix > 0) && "DIVINE".equalsIgnoreCase(source.getSpellType())) {
                    for (Domain d : aPC.getDomainSet()) {
                        if (source.getKeyName().equals(aPC.getDomainSource(d).getPcclass().getKeyName())) {
                            bList = aPC.getSpellsIn(d.get(ObjectKey.DOMAIN_SPELLLIST), ix);
                        }
                    }
                }
                for (CharacterSpell cs : aList) {
                    int x = -1;
                    if (!bList.isEmpty()) {
                        if (bList.contains(cs.getSpell())) {
                            x = 0;
                        }
                    } else {
                        x = cs.getInfoIndexFor(aPC, Constants.EMPTY_STRING, ix, 1);
                    }
                    if (x > -1) {
                        PCClass target = source;
                        String subClassKey = aPC.getSubClassName(source);
                        if (subClassKey != null && (!subClassKey.isEmpty()) && !subClassKey.equals(Constants.NONE)) {
                            target = source.getSubClassKeyed(subClassKey);
                        }
                        adj = aPC.getSpellSupport(target).getSpecialtyKnownForLevel(spellLevel, aPC);
                        break;
                    }
                }
            }
            if (adj > 0) {
                break;
            }
        }
    // end of looping up to this level looking for specialty spells that
    // can be cast
    }
    // end of deciding whether there are specialty slots to distribute
    int mult = (int) aPC.getTotalBonusTo("SPELLCASTMULT", classKeyName + levelSpellLevel);
    mult += (int) aPC.getTotalBonusTo("SPELLCASTMULT", "TYPE." + source.getSpellType() + levelSpellLevel);
    if (mult < 1) {
        mult = 1;
    }
    final int t = getNumFromCastList(pcLevel, spellLevel, aPC);
    total += ((t * mult) + adj);
    BonusSpellInfo bsi = Globals.getContext().getReferenceContext().silentlyGetConstructedCDOMObject(BonusSpellInfo.class, String.valueOf(spellLevel));
    if ((bsi != null) && bsi.isValid()) {
        int base = bsi.getStatScore();
        if (stat >= base) {
            int range = bsi.getStatRange();
            total += Math.max(0, (stat - base + range) / range);
        }
    }
    return total;
}
Also used : ArrayList(java.util.ArrayList) BonusSpellInfo(pcgen.cdom.content.BonusSpellInfo) CharacterSpell(pcgen.core.character.CharacterSpell) Spell(pcgen.core.spell.Spell) CharacterSpell(pcgen.core.character.CharacterSpell)

Example 2 with BonusSpellInfo

use of pcgen.cdom.content.BonusSpellInfo in project pcgen by PCGen.

the class PCClassTest method testGetKnownForLevelSpellstatOther.

public void testGetKnownForLevelSpellstatOther() {
    LoadContext context = Globals.getContext();
    PCClass megaCasterClass = new PCClass();
    megaCasterClass.setName("MegaCasterOther");
    BuildUtilities.setFact(megaCasterClass, "SpellType", "Arcane");
    context.unconditionallyProcess(megaCasterClass, "SPELLSTAT", "OTHER");
    megaCasterClass.put(ObjectKey.SPELLBOOK, false);
    megaCasterClass.put(ObjectKey.MEMORIZE_SPELLS, false);
    context.unconditionallyProcess(megaCasterClass.getOriginalClassLevel(1), "KNOWN", "4,2,2,3,4,5,0");
    context.unconditionallyProcess(megaCasterClass.getOriginalClassLevel(1), "CAST", "3,1,2,3,4,5,0,0");
    context.unconditionallyProcess(megaCasterClass.getOriginalClassLevel(2), "KNOWN", "4,2,2,3,4,5,6,7,8,9,10");
    context.unconditionallyProcess(megaCasterClass.getOriginalClassLevel(2), "CAST", "3,1,2,3,4,5,6,7,8,9,10");
    Globals.getContext().getReferenceContext().importObject(megaCasterClass);
    context.getReferenceContext().buildDerivedObjects();
    context.loadCampaignFacets();
    final PlayerCharacter character = getCharacter();
    // Test retrieval for a non-spell casting class.
    character.incrementClassLevel(1, nqClass);
    PCClass charClass = character.getClassKeyed(nqClass.getKeyName());
    assertEquals("Known 0th level for non spell casting class", 0, character.getSpellSupport(charClass).getKnownForLevel(0, character));
    // Test retrieval for a spell casting class.
    character.incrementClassLevel(1, megaCasterClass);
    charClass = character.getClassKeyed(megaCasterClass.getKeyName());
    setPCStat(character, cha, 10);
    assertEquals("Known 0th level for character's class", 4, character.getSpellSupport(charClass).getKnownForLevel(0, character));
    character.calcActiveBonuses();
    assertEquals("Known 1st level where stat is high enough, but no bonus", 2, character.getSpellSupport(charClass).getKnownForLevel(1, character));
    RuleCheck bonusKnownRule = new RuleCheck();
    bonusKnownRule.setName(RuleConstants.BONUSSPELLKNOWN);
    bonusKnownRule.setDefault(true);
    GameMode gameMode = SettingsHandler.getGame();
    gameMode.getModeContext().getReferenceContext().importObject(bonusKnownRule);
    BonusSpellInfo bsi = new BonusSpellInfo();
    bsi.setName("1");
    bsi.setStatScore(12);
    bsi.setStatRange(8);
    context.getReferenceContext().importObject(bsi);
    bsi = new BonusSpellInfo();
    bsi.setName("5");
    bsi.setStatScore(20);
    bsi.setStatRange(8);
    assertEquals("Known 1st level where stat would give bonus and active", 2, character.getSpellSupport(charClass).getKnownForLevel(1, character));
    assertEquals("Known 2nd level for character's class", 2, character.getSpellSupport(charClass).getKnownForLevel(2, character));
    assertEquals("Known 3rd level for character's class", 3, character.getSpellSupport(charClass).getKnownForLevel(3, character));
    assertEquals("Known 4th level for character's class", 4, character.getSpellSupport(charClass).getKnownForLevel(4, character));
    charClass.put(IntegerKey.KNOWN_SPELLS_FROM_SPECIALTY, 1);
    assertEquals("Known 5th level for character's class", 6, character.getSpellSupport(charClass).getKnownForLevel(5, character));
    assertEquals("Known 6th level for character's class", 0, character.getSpellSupport(charClass).getKnownForLevel(6, character));
    assertEquals("Known 7th level for character's class", 0, character.getSpellSupport(charClass).getKnownForLevel(7, character));
    // Add spell bonus for level above known max
    bsi = new BonusSpellInfo();
    bsi.setName("7");
    bsi.setStatScore(12);
    bsi.setStatRange(8);
    assertEquals("Known 7th level for character's class", 0, character.getSpellSupport(charClass).getKnownForLevel(7, character));
    assertEquals("Known 8th level for character's class", 0, character.getSpellSupport(charClass).getKnownForLevel(8, character));
}
Also used : BonusSpellInfo(pcgen.cdom.content.BonusSpellInfo) LoadContext(pcgen.rules.context.LoadContext)

Example 3 with BonusSpellInfo

use of pcgen.cdom.content.BonusSpellInfo in project pcgen by PCGen.

the class SpellListTokenTest method setUp.

/*
	 * @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.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");
    BuildUtilities.setFact(arcaneClass, "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");
    BuildUtilities.setFact(divineClass, "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);
}
Also used : BonusObj(pcgen.core.bonus.BonusObj) Race(pcgen.core.Race) BonusSpellInfo(pcgen.cdom.content.BonusSpellInfo) LoadContext(pcgen.rules.context.LoadContext) URISyntaxException(java.net.URISyntaxException) UnreachableError(pcgen.base.lang.UnreachableError) PCClass(pcgen.core.PCClass) URI(java.net.URI) SimpleLoader(pcgen.persistence.lst.SimpleLoader)

Example 4 with BonusSpellInfo

use of pcgen.cdom.content.BonusSpellInfo in project pcgen by PCGen.

the class PCClassTest method testGetKnownForLevel.

public void testGetKnownForLevel() {
    LoadContext context = Globals.getContext();
    PCClass megaCasterClass = new PCClass();
    megaCasterClass.setName("MegaCaster");
    BuildUtilities.setFact(megaCasterClass, "SpellType", "Arcane");
    context.unconditionallyProcess(megaCasterClass, "SPELLSTAT", "CHA");
    megaCasterClass.put(ObjectKey.SPELLBOOK, false);
    megaCasterClass.put(ObjectKey.MEMORIZE_SPELLS, false);
    context.unconditionallyProcess(megaCasterClass.getOriginalClassLevel(1), "KNOWN", "4,2,2,3,4,5,0");
    context.unconditionallyProcess(megaCasterClass.getOriginalClassLevel(1), "CAST", "3,1,2,3,4,5,0,0");
    context.unconditionallyProcess(megaCasterClass.getOriginalClassLevel(2), "KNOWN", "4,2,2,3,4,5,6,7,8,9,10");
    context.unconditionallyProcess(megaCasterClass.getOriginalClassLevel(2), "CAST", "3,1,2,3,4,5,6,7,8,9,10");
    Globals.getContext().getReferenceContext().importObject(megaCasterClass);
    context.getReferenceContext().buildDerivedObjects();
    context.loadCampaignFacets();
    final PlayerCharacter character = getCharacter();
    // Test retrieval for a non-spell casting class.
    character.incrementClassLevel(1, nqClass);
    PCClass charClass = character.getClassKeyed(nqClass.getKeyName());
    assertEquals("Known 0th level for non spell casting class", 0, character.getSpellSupport(charClass).getKnownForLevel(0, character));
    // Test retrieval for a spell casting class.
    character.incrementClassLevel(1, megaCasterClass);
    charClass = character.getClassKeyed(megaCasterClass.getKeyName());
    setPCStat(character, cha, 10);
    assertEquals("Known 0th level for character's class", 4, character.getSpellSupport(charClass).getKnownForLevel(0, character));
    assertEquals("Known 1st level where stat is too low", 0, character.getSpellSupport(charClass).getKnownForLevel(1, character));
    setPCStat(character, cha, 11);
    character.calcActiveBonuses();
    assertEquals("Known 1st level where stat is high enough, but no bonus", 2, character.getSpellSupport(charClass).getKnownForLevel(1, character));
    setPCStat(character, cha, 18);
    character.calcActiveBonuses();
    assertEquals("Known 1st level where stat gives bonus but not active", 2, character.getSpellSupport(charClass).getKnownForLevel(1, character));
    RuleCheck bonusKnownRule = new RuleCheck();
    bonusKnownRule.setName(RuleConstants.BONUSSPELLKNOWN);
    bonusKnownRule.setDefault(true);
    GameMode gameMode = SettingsHandler.getGame();
    gameMode.getModeContext().getReferenceContext().importObject(bonusKnownRule);
    BonusSpellInfo bsi = new BonusSpellInfo();
    bsi.setName("1");
    bsi.setStatScore(12);
    bsi.setStatRange(8);
    context.getReferenceContext().importObject(bsi);
    bsi = new BonusSpellInfo();
    bsi.setName("5");
    bsi.setStatScore(20);
    bsi.setStatRange(8);
    assertEquals("Known 1st level where stat gives bonus and active", 3, character.getSpellSupport(charClass).getKnownForLevel(1, character));
    assertEquals("Known 2nd level for character's class", 2, character.getSpellSupport(charClass).getKnownForLevel(2, character));
    assertEquals("Known 3rd level for character's class", 3, character.getSpellSupport(charClass).getKnownForLevel(3, character));
    assertEquals("Known 4th level for character's class", 4, character.getSpellSupport(charClass).getKnownForLevel(4, character));
    charClass.put(IntegerKey.KNOWN_SPELLS_FROM_SPECIALTY, 1);
    assertEquals("Known 5th level for character's class", 6, character.getSpellSupport(charClass).getKnownForLevel(5, character));
    assertEquals("Known 6th level for character's class", 0, character.getSpellSupport(charClass).getKnownForLevel(6, character));
    assertEquals("Known 7th level for character's class", 0, character.getSpellSupport(charClass).getKnownForLevel(7, character));
    // Add spell bonus for level above known max
    bsi = new BonusSpellInfo();
    bsi.setName("7");
    bsi.setStatScore(12);
    bsi.setStatRange(8);
    assertEquals("Known 7th level for character's class", 0, character.getSpellSupport(charClass).getKnownForLevel(7, character));
    assertEquals("Known 8th level for character's class", 0, character.getSpellSupport(charClass).getKnownForLevel(8, character));
}
Also used : BonusSpellInfo(pcgen.cdom.content.BonusSpellInfo) LoadContext(pcgen.rules.context.LoadContext)

Example 5 with BonusSpellInfo

use of pcgen.cdom.content.BonusSpellInfo in project pcgen by PCGen.

the class SpellSupportForPCClass method getKnownForLevel.

public int getKnownForLevel(int spellLevel, PlayerCharacter aPC) {
    int total = 0;
    int stat = 0;
    final String classKeyName = "CLASS." + source.getKeyName();
    final String levelSpellLevel = ";LEVEL." + spellLevel;
    final String allSpellLevel = ";LEVEL.All";
    int pcLevel = aPC.getLevel(source);
    pcLevel += (int) aPC.getTotalBonusTo("PCLEVEL", source.getKeyName());
    pcLevel += (int) aPC.getTotalBonusTo("PCLEVEL", "TYPE." + source.getSpellType());
    /*
		 * CONSIDER Why is known testing getNumFromCastList??? - thpr 11/8/06
		 */
    if (updateSpellCache(false) && spellCache.hasCastProgression() && (getNumFromCastList(pcLevel, spellLevel, aPC) < 0)) {
        // feats
        return (int) aPC.getTotalBonusTo("SPELLKNOWN", classKeyName + levelSpellLevel);
    }
    total += (int) aPC.getTotalBonusTo("SPELLKNOWN", classKeyName + levelSpellLevel);
    total += (int) aPC.getTotalBonusTo("SPELLKNOWN", "TYPE." + source.getSpellType() + levelSpellLevel);
    total += (int) aPC.getTotalBonusTo("SPELLKNOWN", "CLASS.Any" + levelSpellLevel);
    total += (int) aPC.getTotalBonusTo("SPELLKNOWN", classKeyName + allSpellLevel);
    total += (int) aPC.getTotalBonusTo("SPELLKNOWN", "TYPE." + source.getSpellType() + allSpellLevel);
    total += (int) aPC.getTotalBonusTo("SPELLKNOWN", "CLASS.Any" + allSpellLevel);
    PCStat aStat = source.baseSpellStat();
    String statString = Constants.NONE;
    if (aStat != null) {
        stat = aPC.getTotalStatFor(aStat);
        statString = aStat.getKeyName();
    }
    final int bonusStat = (int) aPC.getTotalBonusTo("STAT", "KNOWN." + statString) + (int) aPC.getTotalBonusTo("STAT", "BASESPELLKNOWNSTAT") + (int) aPC.getTotalBonusTo("STAT", "BASESPELLKNOWNSTAT;CLASS=" + source.getKeyName());
    if (!source.getSafe(ObjectKey.USE_SPELL_SPELL_STAT) && !source.getSafe(ObjectKey.CASTER_WITHOUT_SPELL_STAT)) {
        final int maxSpellLevel = aPC.getVariableValue("MAXLEVELSTAT=" + statString, "").intValue();
        if ((maxSpellLevel + bonusStat) < spellLevel) {
            return total;
        }
    }
    stat += bonusStat;
    int mult = (int) aPC.getTotalBonusTo("SPELLKNOWNMULT", classKeyName + levelSpellLevel);
    mult += (int) aPC.getTotalBonusTo("SPELLKNOWNMULT", "TYPE." + source.getSpellType() + levelSpellLevel);
    if (mult < 1) {
        mult = 1;
    }
    if (!updateSpellCache(false)) {
        return total;
    }
    if (spellCache.hasKnownProgression()) {
        List<Formula> knownList = spellCache.getKnownForLevel(pcLevel);
        if (spellLevel >= 0 && knownList != null && spellLevel < knownList.size()) {
            total += mult * knownList.get(spellLevel).resolve(aPC, "").intValue();
            // add Stat based bonus
            BonusSpellInfo bsi = Globals.getContext().getReferenceContext().silentlyGetConstructedCDOMObject(BonusSpellInfo.class, String.valueOf(spellLevel));
            if (Globals.checkRule(RuleConstants.BONUSSPELLKNOWN) && (bsi != null) && bsi.isValid()) {
                int base = bsi.getStatScore();
                if (stat >= base) {
                    int range = bsi.getStatRange();
                    total += Math.max(0, (stat - base + range) / range);
                }
            }
        }
    }
    // or a psi specialty.
    if (total > 0 && spellLevel > 0) {
        // make sure any slots due from specialties
        total += source.getSafe(IntegerKey.KNOWN_SPELLS_FROM_SPECIALTY);
        // (including domains) are added
        Integer assoc = aPC.getDomainSpellCount(source);
        if (assoc != null) {
            total += assoc;
        }
    }
    // Add in any from SPELLKNOWN
    total += aPC.getKnownSpellCountForLevel(source.get(ObjectKey.CLASS_SPELLLIST), spellLevel);
    return total;
}
Also used : Formula(pcgen.base.formula.Formula) BonusSpellInfo(pcgen.cdom.content.BonusSpellInfo)

Aggregations

BonusSpellInfo (pcgen.cdom.content.BonusSpellInfo)5 LoadContext (pcgen.rules.context.LoadContext)3 URI (java.net.URI)1 URISyntaxException (java.net.URISyntaxException)1 ArrayList (java.util.ArrayList)1 Formula (pcgen.base.formula.Formula)1 UnreachableError (pcgen.base.lang.UnreachableError)1 PCClass (pcgen.core.PCClass)1 Race (pcgen.core.Race)1 BonusObj (pcgen.core.bonus.BonusObj)1 CharacterSpell (pcgen.core.character.CharacterSpell)1 Spell (pcgen.core.spell.Spell)1 SimpleLoader (pcgen.persistence.lst.SimpleLoader)1