public void setLevel(final int newLevel, final PlayerCharacter aPC) { final int curLevel = aPC.getLevel(this); if (newLevel >= 0) { aPC.setLevelWithoutConsequence(this, newLevel); } if (newLevel == 1) { if (newLevel > curLevel || aPC.isImporting()) { addFeatPoolBonus(aPC); } } if (!aPC.isImporting()) { aPC.calcActiveBonuses(); // Need to do this again if caching is re-integrated // aPC.getSpellTracker().buildSpellLevelMap(newLevel); } if ((newLevel == 1) && !aPC.isImporting() && (curLevel == 0)) { SubClassApplication.checkForSubClass(aPC, this); aPC.setSpellLists(this); } if (!aPC.isImporting() && (curLevel < newLevel)) { SubstitutionClassApplication.checkForSubstitutionClass(this, newLevel, aPC); } for (PCClass pcClass : aPC.getClassSet()) { aPC.calculateKnownSpellsForClassLevel(this); } }
void subLevel(final PlayerCharacter aPC) { if (aPC != null) { int total = aPC.getTotalLevels(); int oldLevel = aPC.getLevel(this); int spMod = 0; final PCLevelInfo pcl = aPC.getLevelInfoFor(getKeyName(), oldLevel); if (pcl != null) { spMod = pcl.getSkillPointsGained(aPC); } else { Logging.errorPrint( "ERROR: could not find class/level info for " + getDisplayName() + "/" + oldLevel); } final int newLevel = oldLevel - 1; if (oldLevel > 0) { PCClassLevel classLevel = aPC.getActiveClassLevel(this, oldLevel - 1); aPC.removeHP(classLevel); } // aPC.adjustFeats(-aPC.getBonusFeatsForNewLevel(this)); setLevel(newLevel, aPC); aPC.removeKnownSpellsForClassLevel(this); doMinusLevelMods(aPC, newLevel + 1); DomainApplication.removeDomainsForLevel(this, newLevel + 1, aPC); if (newLevel == 0) { SubClassApplication.setSubClassKey(aPC, this, Constants.NONE); // // Remove all skills associated with this class // for (Skill skill : aPC.getSkillSet()) { SkillRankControl.setZeroRanks(this, aPC, skill); } Integer currentPool = aPC.getSkillPool(this); spMod = currentPool == null ? 0 : currentPool; } if (!isMonster() && (total > aPC.getTotalLevels())) { total = aPC.getTotalLevels(); // Roll back any stat changes that were made as part of the // level final List<PCLevelInfoStat> moddedStats = new ArrayList<>(); if (pcl.getModifiedStats(true) != null) { moddedStats.addAll(pcl.getModifiedStats(true)); } if (pcl.getModifiedStats(false) != null) { moddedStats.addAll(pcl.getModifiedStats(false)); } if (!moddedStats.isEmpty()) { for (PCLevelInfoStat statToRollback : moddedStats) { for (PCStat aStat : aPC.getStatSet()) { if (aStat.equals(statToRollback.getStat())) { aPC.setStat(aStat, aPC.getStat(aStat) - statToRollback.getStatMod()); break; } } } } } aPC.setLevelWithoutConsequence(this, newLevel); if (isMonster() || (total != 0)) { Integer currentPool = aPC.getSkillPool(this); int newSkillPool = (currentPool == null ? 0 : currentPool) - spMod; aPC.setSkillPool(this, newSkillPool); aPC.setDirty(true); } if (aPC.getLevel(this) == 0) { aPC.removeClass(this); } aPC.validateCharacterDomains(); if (!aPC.isImporting()) { final int maxxp = aPC.minXPForNextECL(); if (aPC.getXP() >= maxxp) { aPC.setXP(Math.max(maxxp - 1, 0)); } } } else { Logging.errorPrint("No current pc in subLevel()? How did this happen?"); return; } }