Search in sources :

Example 16 with PCLevelInfo

use of pcgen.core.pclevelinfo.PCLevelInfo in project pcgen by PCGen.

the class PlayerCharacterTest method testCheckSkillModChangeWithBonus.

/**
	 * Validate the checkSkillModChange correctly handles SKILLPOOL bonuses
	 */
public void testCheckSkillModChangeWithBonus() {
    readyToRun();
    PlayerCharacter character = getCharacter();
    character.setRace(human);
    character.setStat(intel, 10);
    PCTemplate template = TestHelper.makeTemplate("grantsskills");
    LoadContext context = Globals.getContext();
    final BonusObj skillBonusLvl1 = Bonus.newBonus(context, "SKILLPOOL|CLASS=MyClass;LEVEL=1|2");
    assertNotNull("Failed to create bonus", skillBonusLvl1);
    template.addToListFor(ListKey.BONUS, skillBonusLvl1);
    character.addTemplate(template);
    character.incrementClassLevel(2, pcClass, true);
    List<PCLevelInfo> levelInfoList = new ArrayList<>(character.getLevelInfo());
    assertEquals("Level number lvl 1", 1, levelInfoList.get(0).getClassLevel());
    assertEquals("Level number lvl 2", 2, levelInfoList.get(1).getClassLevel());
    assertEquals("Skills gained lvl 1", 3, levelInfoList.get(0).getSkillPointsGained(character));
    assertEquals("Skills remaining lvl 1", 3, levelInfoList.get(0).getSkillPointsRemaining());
    assertEquals("Skills gained lvl 2", 1, levelInfoList.get(1).getSkillPointsGained(character));
    assertEquals("Skills remaining lvl 2", 1, levelInfoList.get(1).getSkillPointsRemaining());
    character.checkSkillModChange();
    character.checkSkillModChange();
    assertEquals("Skills gained lvl 1", 3, levelInfoList.get(0).getSkillPointsGained(character));
    assertEquals("Skills remaining lvl 1", 3, levelInfoList.get(0).getSkillPointsRemaining());
    assertEquals("Skills gained lvl 2", 1, levelInfoList.get(1).getSkillPointsGained(character));
    assertEquals("Skills remaining lvl 2", 1, levelInfoList.get(1).getSkillPointsRemaining());
}
Also used : BonusObj(pcgen.core.bonus.BonusObj) ArrayList(java.util.ArrayList) LoadContext(pcgen.rules.context.LoadContext) PCLevelInfo(pcgen.core.pclevelinfo.PCLevelInfo)

Example 17 with PCLevelInfo

use of pcgen.core.pclevelinfo.PCLevelInfo in project pcgen by PCGen.

the class CharacterLevelsFacadeImplTest method testFindNextLevelForSkillCrossClass2Points.

/**
	 * Test method for {@link pcgen.gui2.facade.CharacterLevelsFacadeImpl#findNextLevelForSkill(pcgen.core.facade.SkillFacade, pcgen.core.facade.CharacterLevelFacade, float)}
	 * to check level selection where cross-class skills cost 2 points and class 
	 * skills cost only 1. 
	 */
@Test
public void testFindNextLevelForSkillCrossClass2Points() {
    // Set game mode skill cost to be double for cross-class
    setGameSkillRankData(true);
    PlayerCharacter pc = getCharacter();
    pc.incrementClassLevel(4, fighterClass);
    pc.incrementClassLevel(4, wizardClass);
    pc.incrementClassLevel(3, fighterClass);
    pc.incrementClassLevel(3, wizardClass);
    pc.incrementClassLevel(3, fighterClass);
    pc.incrementClassLevel(3, wizardClass);
    assertTrue("Climb should be class for fighter", pc.isClassSkill(fighterClass, climbSkill));
    assertFalse("Spellcraft should not be class for fighter", pc.isClassSkill(fighterClass, spellcraftSkill));
    assertTrue("UMD should be class for fighter", pc.isClassSkill(fighterClass, umdSkill));
    assertFalse("Climb should not be class for wizard", pc.isClassSkill(wizardClass, climbSkill));
    assertTrue("Spellcraft should be class for wizard", pc.isClassSkill(wizardClass, spellcraftSkill));
    assertFalse("UMD should be class for wizard", pc.isClassSkill(wizardClass, umdSkill));
    CharacterLevelsFacadeImpl charLvlsFI = new CharacterLevelsFacadeImpl(pc, delegate, todoManager, dataSetFacade, null);
    // Rules for finding the next level to spend a point:
    // 1. Selected level, if points available and not exceeding max ranks.
    assertEquals("Level for 1 rank spellcraft", charLvlsFI.getElementAt(2), charLvlsFI.findNextLevelForSkill(spellcraftSkill, charLvlsFI.getElementAt(2), 1.0f));
    assertEquals("Level for 7 ranks climb", charLvlsFI.getElementAt(3), charLvlsFI.findNextLevelForSkill(climbSkill, charLvlsFI.getElementAt(3), 7.0f));
    assertEquals("Level for 7.5 ranks climb", charLvlsFI.getElementAt(4), charLvlsFI.findNextLevelForSkill(climbSkill, charLvlsFI.getElementAt(4), 7.5f));
    // 2. Scan forward from selected level for first level with points spare 
    // where the rank is not above max rank for the level and the cost is 
    // equal to class cost
    assertEquals("Level for 3 ranks spellcraft", charLvlsFI.getElementAt(4), charLvlsFI.findNextLevelForSkill(spellcraftSkill, charLvlsFI.getElementAt(1), 3.0f));
    assertEquals("Level for 9 ranks spellcraft", charLvlsFI.getElementAt(5), charLvlsFI.findNextLevelForSkill(spellcraftSkill, charLvlsFI.getElementAt(1), 9.0f));
    // not prohibited
    for (int i = 0; i < 20; i++) {
        PCLevelInfo pcLevelInfo = charLvlsFI.getLevelInfo(charLvlsFI.getElementAt(i));
        if (pcLevelInfo.getClassKeyName().equals(wizardClass.getKeyName())) {
            pcLevelInfo.setSkillPointsRemaining(0);
        }
    }
    assertEquals("Level for 5 ranks spellcraft", charLvlsFI.getElementAt(8), charLvlsFI.findNextLevelForSkill(spellcraftSkill, charLvlsFI.getElementAt(5), 5.0f));
    // 5. Scan from level 1 for first level with points spare where the rank 
    // is not above max rank for the level and the skill is not prohibited
    assertEquals("Level for 3 ranks spellcraft", charLvlsFI.getElementAt(2), charLvlsFI.findNextLevelForSkill(spellcraftSkill, charLvlsFI.getElementAt(19), 3.0f));
    // 6. Advise that the skill cannot be advanced.
    charLvlsFI.getLevelInfo(charLvlsFI.getElementAt(18)).setSkillPointsRemaining(4);
    charLvlsFI.getLevelInfo(charLvlsFI.getElementAt(19)).setSkillPointsRemaining(4);
    assertNull("Level for rank 23.5 climb - cannot be advanced", charLvlsFI.findNextLevelForSkill(climbSkill, charLvlsFI.getElementAt(2), 23.5f));
}
Also used : PlayerCharacter(pcgen.core.PlayerCharacter) PCLevelInfo(pcgen.core.pclevelinfo.PCLevelInfo) Test(org.junit.Test)

Example 18 with PCLevelInfo

use of pcgen.core.pclevelinfo.PCLevelInfo in project pcgen by PCGen.

the class PCClassTest method testMonsterSkillPoints.

/**
	 * Test monster classes generating the correct number of skill points.
	 */
public void testMonsterSkillPoints() {
    // Create a medium bugbear first level
    PlayerCharacter bugbear = new PlayerCharacter();
    bugbear.setRace(bugbearRace);
    setPCStat(bugbear, intel, 12);
    // Test skills granted for each level
    bugbear.incrementClassLevel(1, humanoidClass);
    PCLevelInfo levelInfo = bugbear.getLevelInfo(0);
    assertEquals("First level of bugbear", 7, levelInfo.getSkillPointsGained(bugbear));
    bugbear.incrementClassLevel(1, humanoidClass);
    levelInfo = bugbear.getLevelInfo(1);
    assertEquals("2nd level of bugbear", 1, levelInfo.getSkillPointsGained(bugbear));
    bugbear.incrementClassLevel(1, humanoidClass);
    levelInfo = bugbear.getLevelInfo(2);
    assertEquals("3rd level of bugbear", 1, levelInfo.getSkillPointsGained(bugbear));
    // Craete a huge bugbear first level
    bugbear = new PlayerCharacter();
    bugbear.setRace(bigBugbearRace);
    assertEquals("big bugbear", "L", bugbear.getDisplay().getSize());
    setPCStat(bugbear, intel, 10);
    bugbear.incrementClassLevel(1, humanoidClass);
    // Test skills granted for each level
    levelInfo = bugbear.getLevelInfo(0);
    assertEquals("First level of big bugbear", 6, levelInfo.getSkillPointsGained(bugbear));
    bugbear.incrementClassLevel(1, humanoidClass);
    levelInfo = bugbear.getLevelInfo(1);
    assertEquals("2nd level of big bugbear", 0, levelInfo.getSkillPointsGained(bugbear));
    bugbear.incrementClassLevel(1, humanoidClass);
    levelInfo = bugbear.getLevelInfo(2);
    assertEquals("3rd level of big bugbear", 1, levelInfo.getSkillPointsGained(bugbear));
    // Create a nymph - first level
    PlayerCharacter nymph = new PlayerCharacter();
    nymph.setRace(nymphRace);
    assertEquals("nymph", "M", nymph.getDisplay().getSize());
    setPCStat(nymph, intel, 10);
    nymph.incrementClassLevel(1, nymphClass);
    // Test skills granted for each level
    levelInfo = nymph.getLevelInfo(0);
    assertEquals("First level of nymph", 24, levelInfo.getSkillPointsGained(bugbear));
    nymph.incrementClassLevel(1, nymphClass);
    levelInfo = nymph.getLevelInfo(1);
    assertEquals("2nd level of nymph", 6, levelInfo.getSkillPointsGained(bugbear));
}
Also used : PCLevelInfo(pcgen.core.pclevelinfo.PCLevelInfo)

Example 19 with PCLevelInfo

use of pcgen.core.pclevelinfo.PCLevelInfo in project pcgen by PCGen.

the class CharacterFacadeImpl method addDomain.

/**
	 * @see pcgen.core.facade.CharacterFacade#addDomain(pcgen.core.facade.DomainFacade)
	 */
@Override
public void addDomain(DomainFacade domainFacade) {
    if (!(domainFacade instanceof DomainFacadeImpl)) {
        return;
    }
    DomainFacadeImpl domainFI = (DomainFacadeImpl) domainFacade;
    Domain domain = domainFI.getRawObject();
    if (charDisplay.hasDomain(domain)) {
        return;
    }
    if (!isQualifiedFor(domainFacade)) {
        delegate.showErrorMessage(Constants.APPLICATION_NAME, LanguageBundle.getFormattedString("in_qualifyMess", domain.getDisplayName()));
        return;
    }
    // Check selected domains vs Max number allowed
    if (charDisplay.getDomainCount() >= theCharacter.getMaxCharacterDomains()) {
        delegate.showErrorMessage(Constants.APPLICATION_NAME, LanguageBundle.getFormattedString("in_errorNoMoreDomains"));
        return;
    }
    if (!theCharacter.hasDefaultDomainSource()) {
        // No source for the domain yet? Default to the last added class level
        int level = charDisplay.getLevelInfoSize();
        PCLevelInfo highestLevelInfo = charDisplay.getLevelInfo(level - 1);
        PCClass cls = theCharacter.getClassKeyed(highestLevelInfo.getClassKeyName());
        theCharacter.setDefaultDomainSource(new ClassSource(cls, highestLevelInfo.getClassLevel()));
    }
    if (theCharacter.addDomain(domain)) {
        domains.addElement(domainFI);
        DomainApplication.applyDomain(theCharacter, domain);
        theCharacter.calcActiveBonuses();
        remainingDomains.set(theCharacter.getMaxCharacterDomains() - charDisplay.getDomainCount());
        updateDomainTodo();
        spellSupportFacade.refreshAvailableKnownSpells();
        companionSupportFacade.refreshCompanionData();
    }
}
Also used : PCLevelInfo(pcgen.core.pclevelinfo.PCLevelInfo) Domain(pcgen.core.Domain) PCClass(pcgen.core.PCClass) ClassSource(pcgen.cdom.helper.ClassSource)

Example 20 with PCLevelInfo

use of pcgen.core.pclevelinfo.PCLevelInfo in project pcgen by PCGen.

the class PlayerCharacter method incrementClassLevel.

/**
	 * Change the number of levels a character has in a particular class. Note:
	 * It is assumed that this method is not used as part of loading a
	 * previously saved character.
	 *
	 * @param numberOfLevels
	 *            The number of levels to add or remove. If a positive number is
	 *            passed in then that many levels will be added. If the number
	 *            of levels passed in is negative then that many levels will be
	 *            removed from the specified class.
	 * @param globalClass
	 *            The global class from the data store. The class as stored in
	 *            the character will be compared to this one using the
	 *            getClassNamed() method
	 * @param bSilent
	 *            If true do not display any warning messages about adding or
	 *            removing too many levels
	 * @param bypassPrereqs
	 *            Whether we should bypass the checks as to whether or not the
	 *            PC qualifies to take this class. If true, the checks will be
	 *            bypassed
	 */
public void incrementClassLevel(final int numberOfLevels, final PCClass globalClass, final boolean bSilent, final boolean bypassPrereqs) {
    // If not importing, load the spell list
    if (!importing) {
        getSpellList();
    }
    // Make sure the character qualifies for the class if adding it
    if (numberOfLevels > 0) {
        if (!bypassPrereqs && !globalClass.qualifies(this, globalClass)) {
            return;
        }
        Race race = getRace();
        if (globalClass.isMonster() && !SettingsHandler.isIgnoreMonsterHDCap() && !race.isAdvancementUnlimited() && ((totalHitDice() + numberOfLevels) > race.maxHitDiceAdvancement()) && !bSilent) {
            ShowMessageDelegate.showMessageDialog("Cannot increase Monster Hit Dice for this character beyond " + race.maxHitDiceAdvancement() + ". This character's current number of Monster Hit Dice is " + totalHitDice(), Constants.APPLICATION_NAME, MessageType.INFORMATION);
            return;
        }
    }
    // Check if the character already has the class.
    PCClass pcClassClone = getClassKeyed(globalClass.getKeyName());
    // If the character did not already have the class...
    if (pcClassClone == null) {
        // add the class even if setting to level 0
        if (numberOfLevels >= 0) {
            // Get a clone of the class so we don't modify the globals!
            //Still required :(
            pcClassClone = globalClass.clone();
            // Make sure the clone was successful
            if (pcClassClone == null) {
                Logging.errorPrint("PlayerCharacter::incrementClassLevel => " + "Clone of class " + globalClass.getKeyName() + " failed!");
                return;
            }
            // If not importing, add extra feats
            if (!importing && classFacet.isEmpty(id)) {
                adjustAbilities(AbilityCategory.FEAT, new BigDecimal(pcClassClone.getSafe(IntegerKey.START_FEATS)));
            }
            // Add the class to the character classes as level 0
            classFacet.addClass(id, pcClassClone);
        } else {
            // mod is < 0 and character does not have class. Return.
            return;
        }
    }
    // Add or remove levels as needed
    if (numberOfLevels > 0) {
        for (int i = 0; i < numberOfLevels; ++i) {
            int currentLevel = getLevel(pcClassClone);
            final PCLevelInfo playerCharacterLevelInfo = addLevelInfo(pcClassClone.getKeyName());
            // if we fail to add the level, remove and return
            if (!pcClassClone.addLevel(false, bSilent, this, bypassPrereqs)) {
                PCClassLevel failedpcl = getActiveClassLevel(pcClassClone, currentLevel + 1);
                removeLevelInfo(pcClassClone.getKeyName());
                return;
            }
        }
    } else if (numberOfLevels < 0) {
        for (int i = 0; i < -numberOfLevels; ++i) {
            int currentLevel = getLevel(pcClassClone);
            pcClassClone.subLevel(this);
            PCLevelInfo removedLI = removeLevelInfo(pcClassClone.getKeyName());
            int pointsToRemove = removedLI.getSkillPointsGained(this) - removedLI.getSkillPointsRemaining();
            SkillRankControl.removeSkillsForTopLevel(this, pcClassClone, currentLevel, pointsToRemove);
        }
    }
    calcActiveBonuses();
}
Also used : PCLevelInfo(pcgen.core.pclevelinfo.PCLevelInfo) BigDecimal(java.math.BigDecimal) PCClassLevel(pcgen.cdom.inst.PCClassLevel)

Aggregations

PCLevelInfo (pcgen.core.pclevelinfo.PCLevelInfo)33 PCClass (pcgen.core.PCClass)11 PCClassLevel (pcgen.cdom.inst.PCClassLevel)9 ArrayList (java.util.ArrayList)5 HashMap (java.util.HashMap)3 Skill (pcgen.core.Skill)3 StringTokenizer (java.util.StringTokenizer)2 CDOMObject (pcgen.cdom.base.CDOMObject)2 LevelCommandFactory (pcgen.cdom.content.LevelCommandFactory)2 ClassSource (pcgen.cdom.helper.ClassSource)2 Language (pcgen.core.Language)2 PlayerCharacter (pcgen.core.PlayerCharacter)2 SpecialAbility (pcgen.core.SpecialAbility)2 SpellProhibitor (pcgen.core.SpellProhibitor)2 BonusObj (pcgen.core.bonus.BonusObj)2 PCLevelInfoStat (pcgen.core.pclevelinfo.PCLevelInfoStat)2 BigDecimal (java.math.BigDecimal)1 TreeSet (java.util.TreeSet)1 Test (org.junit.Test)1 HitDie (pcgen.cdom.content.HitDie)1