use of pcgen.cdom.helper.ClassSource in project pcgen by PCGen.
the class AbstractAddListTokenTest method testFromDomain.
@Test
public void testFromDomain() throws PersistenceLayerException {
Domain source = create(Domain.class, "Source");
PCClass pcc = create(PCClass.class, "Class");
T granted = createGrantedObject();
processToken(source);
assertEquals(0, getCount());
ClassSource classSource = new ClassSource(pcc);
domainFacet.add(id, source, classSource);
assertTrue(containsExpected(granted));
assertEquals(1, getCount());
domainFacet.remove(id, source, classSource);
assertEquals(0, getCount());
assertTrue(cleanedSideEffects());
}
use of pcgen.cdom.helper.ClassSource in project pcgen by PCGen.
the class PlayerCharacter method getDC.
public int getDC(final Spell sp, PCClass aClass, int spellLevel, int metaDC, CDOMObject ow) {
String bonDomain = "";
if (ow instanceof Domain) {
bonDomain = "DOMAIN." + ow.getKeyName();
ClassSource source = getDomainSource((Domain) ow);
if (source != null) {
aClass = getClassKeyed(source.getPcclass().getKeyName());
}
}
boolean useStatFromSpell = false;
String bonClass = "";
String spellType = "";
String classKey = "";
if ((aClass != null) || (ow instanceof PCClass)) {
if ((aClass == null) || (ow instanceof PCClass)) {
aClass = (PCClass) ow;
}
bonClass = "CLASS." + aClass.getKeyName();
classKey = "CLASS:" + aClass.getKeyName();
spellType = aClass.getSpellType();
useStatFromSpell = aClass.getSafe(ObjectKey.USE_SPELL_SPELL_STAT);
}
if (!(ow instanceof PCClass) && !(ow instanceof Domain)) {
// get BASESPELLSTAT from spell itself
useStatFromSpell = true;
}
// set the spell Level used in aPC.getVariableValue()
// Explicitly should *not* set the dirty flag to true.
spellLevelTemp = spellLevel;
// must be done after spellLevel is set above
int dc = getVariableValue(SettingsHandler.getGame().getSpellBaseDC(), classKey).intValue() + metaDC;
dc += (int) getTotalBonusTo("DC", "ALLSPELLS");
if (useStatFromSpell) {
// get the BASESPELLSTAT from the spell itself
CDOMSingleRef<PCStat> stat = sp.get(ObjectKey.SPELL_STAT);
if (stat != null) {
dc += this.getStatModFor(stat.get());
}
}
if (!sp.getKeyName().isEmpty()) {
dc += (int) getTotalBonusTo("DC", "SPELL." + sp.getKeyName());
}
// DOMAIN.name
if (!bonDomain.isEmpty()) {
dc += (int) getTotalBonusTo("DC", bonDomain);
}
// CLASS.name
if (!bonClass.isEmpty()) {
dc += (int) getTotalBonusTo("DC", bonClass);
}
dc += (int) getTotalBonusTo("DC", "TYPE." + spellType);
if (spellType.equals("ALL")) {
for (Type aType : sp.getTrueTypeList(false)) {
dc += (int) getTotalBonusTo("DC", "TYPE." + aType);
}
}
for (SpellSchool aType : sp.getSafeListFor(ListKey.SPELL_SCHOOL)) {
dc += (int) getTotalBonusTo("DC", "SCHOOL." + aType.toString());
}
for (String aType : sp.getSafeListFor(ListKey.SPELL_SUBSCHOOL)) {
dc += (int) getTotalBonusTo("DC", "SUBSCHOOL." + aType);
}
for (String aType : sp.getSafeListFor(ListKey.SPELL_DESCRIPTOR)) {
dc += (int) getTotalBonusTo("DC", "DESCRIPTOR." + aType);
}
// Explicitly should *not* set the dirty flag to true.
spellLevelTemp = 0;
return dc;
}
use of pcgen.cdom.helper.ClassSource in project pcgen by PCGen.
the class PCClass method addLevel.
/**
* Adds a level of this class to the character.
*
* TODO: Split the PlayerCharacter code out of PCClass (i.e. the level
* property). Then have a joining class assigned to PlayerCharacter that
* maps PCClass and number of levels in the class.
*
*
* @param argLevelMax
* True if we should only allow extra levels if there are still
* levels in this class to take. (i.e. a lot of prestige classes
* stop at level 10, so if this is true it would not allow an
* 11th level of the class to be added
* @param bSilent
* True if we are not to show any dialog boxes about errors or
* questions.
* @param aPC
* The character we are adding the level to.
* @param ignorePrereqs
* True if prereqs for the level should be ignored. Used in
* situations such as when the character is being loaded.
* @return true or false
*/
/*
* REFACTOR Clearly this is part of the PCClass factory method that produces
* PCClassLevels combined with some other work that will need to be done to
* extract some of the complicated gunk out of here that goes out and puts
* information into PCLevelInfo and PlayerCharacter.
*/
public boolean addLevel(final boolean argLevelMax, final boolean bSilent, final PlayerCharacter aPC, final boolean ignorePrereqs) {
// Check to see if we can add a level of this class to the
// current character
final int newLevel = aPC.getLevel(this) + 1;
boolean levelMax = argLevelMax;
aPC.setAllowInteraction(false);
aPC.setLevelWithoutConsequence(this, newLevel);
if (!ignorePrereqs) {
// When loading a character, classes are added before feats, so
// this test would always fail on loading if feats are required
boolean doReturn = false;
if (!qualifies(aPC, this)) {
doReturn = true;
if (!bSilent) {
ShowMessageDelegate.showMessageDialog("This character does not qualify for level " + newLevel, Constants.APPLICATION_NAME, MessageType.ERROR);
}
}
aPC.setLevelWithoutConsequence(this, newLevel - 1);
if (doReturn) {
return false;
}
}
aPC.setAllowInteraction(true);
if (isMonster()) {
levelMax = false;
}
if (hasMaxLevel() && (newLevel > getSafe(IntegerKey.LEVEL_LIMIT)) && levelMax) {
if (!bSilent) {
ShowMessageDelegate.showMessageDialog("This class cannot be raised above level " + Integer.toString(getSafe(IntegerKey.LEVEL_LIMIT)), Constants.APPLICATION_NAME, MessageType.ERROR);
}
return false;
}
// Add the level to the current character
int total = aPC.getTotalLevels();
// No longer need this since the race now sets a bonus itself and Templates
// are not able to reassign their feats. There was nothing else returned in
// this number
// if (total == 0) {
// aPC.setFeats(aPC.getInitialFeats());
// }
setLevel(newLevel, aPC);
// the level has now been added to the character,
// so now assign the attributes of this class level to the
// character...
PCClassLevel classLevel = aPC.getActiveClassLevel(this, newLevel);
// Make sure that if this Class adds a new domain that
// we record where that domain came from
final int dnum = aPC.getMaxCharacterDomains(this, aPC) - aPC.getDomainCount();
if (dnum > 0 && !aPC.hasDefaultDomainSource()) {
aPC.setDefaultDomainSource(new ClassSource(this, newLevel));
}
// out
if (Globals.getUseGUI()) {
final int levels = SettingsHandler.isHPMaxAtFirstClassLevel() ? aPC.totalNonMonsterLevels() : aPC.getTotalLevels();
final boolean isFirst = levels == 1;
aPC.rollHP(this, aPC.getLevel(this), isFirst);
}
if (!aPC.isImporting()) {
DomainApplication.addDomainsUpToLevel(this, newLevel, aPC);
}
int levelUpStats = 0;
// i.e. a bonus feat every 3 levels
if (aPC.getTotalLevels() > total) {
boolean processBonusStats = true;
total = aPC.getTotalLevels();
if (isMonster()) {
// If we have less levels that the races monster levels
// then we can not give a stat bonus (i.e. an Ogre has
// 4 levels of Giant, so it does not get a stat increase at
// 4th level because that is already taken into account in
// its racial stat modifiers, but it will get one at 8th
LevelCommandFactory lcf = aPC.getRace().get(ObjectKey.MONSTER_CLASS);
int monLevels = 0;
if (lcf != null) {
monLevels = lcf.getLevelCount().resolve(aPC, "").intValue();
}
if (total <= monLevels) {
processBonusStats = false;
}
}
if (!aPC.isImporting()) {
if (processBonusStats) {
final int bonusStats = Globals.getBonusStatsForLevel(total, aPC);
if (bonusStats > 0) {
aPC.setPoolAmount(aPC.getPoolAmount() + bonusStats);
if (!bSilent && SettingsHandler.getShowStatDialogAtLevelUp()) {
levelUpStats = StatApplication.askForStatIncrease(aPC, bonusStats, true);
}
}
}
}
}
int spMod = getSkillPointsForLevel(aPC, classLevel, total);
PCLevelInfo pcl;
if (aPC.getLevelInfoSize() > 0) {
pcl = aPC.getLevelInfo(aPC.getLevelInfoSize() - 1);
if (pcl != null) {
pcl.setClassLevel(aPC.getLevel(this));
pcl.setSkillPointsGained(aPC, spMod);
pcl.setSkillPointsRemaining(pcl.getSkillPointsGained(aPC));
}
}
Integer currentPool = aPC.getSkillPool(this);
int newSkillPool = spMod + (currentPool == null ? 0 : currentPool);
aPC.setSkillPool(this, newSkillPool);
if (!aPC.isImporting()) {
//
if (levelUpStats > 0) {
StatApplication.askForStatIncrease(aPC, levelUpStats, false);
}
if (newLevel == 1) {
AddObjectActions.doBaseChecks(this, aPC);
CDOMObjectUtilities.addAdds(this, aPC);
CDOMObjectUtilities.checkRemovals(this, aPC);
}
for (TransitionChoice<Kit> kit : classLevel.getSafeListFor(ListKey.KIT_CHOICE)) {
kit.act(kit.driveChoice(aPC), classLevel, aPC);
}
TransitionChoice<Region> region = classLevel.get(ObjectKey.REGION_CHOICE);
if (region != null) {
region.act(region.driveChoice(aPC), classLevel, aPC);
}
}
// this is a monster class, so don't worry about experience
if (isMonster()) {
return true;
}
if (!aPC.isImporting()) {
CDOMObjectUtilities.checkRemovals(this, aPC);
final int minxp = aPC.minXPForECL();
if (aPC.getXP() < minxp) {
aPC.setXP(minxp);
} else if (aPC.getXP() >= aPC.minXPForNextECL()) {
if (!bSilent) {
ShowMessageDelegate.showMessageDialog(SettingsHandler.getGame().getLevelUpMessage(), Constants.APPLICATION_NAME, MessageType.INFORMATION);
}
}
}
//
if (containsKey(ObjectKey.EXCHANGE_LEVEL) && (aPC.getLevel(this) == 1) && !aPC.isImporting()) {
ExchangeLevelApplication.exchangeLevels(aPC, this);
}
return true;
}
use of pcgen.cdom.helper.ClassSource in project pcgen by PCGen.
the class DomainApplication method addDomain.
private static void addDomain(final PlayerCharacter aPC, PCClass cl, Domain d) {
if (d.qualifies(aPC, d)) {
// TODO Not entirely correct, as this takes this level, not
// the level where BONUS DOMAINS was present
ClassSource cs = new ClassSource(cl, aPC.getLevel(cl));
aPC.addDomain(d, cs);
applyDomain(aPC, d);
}
}
use of pcgen.cdom.helper.ClassSource in project pcgen by PCGen.
the class DomainApplication method applyDomain.
/**
* 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);
}
}
}
}
}
Aggregations