use of pcgen.core.PCClass in project pcgen by PCGen.
the class ChallengeRatingFacet method calcClassesForRaceCR.
private Integer calcClassesForRaceCR(CharID id) {
int cr = 0;
int levelsKey = 0;
int levelsNonKey = 0;
int levelsConverted = 0;
int threshold = 0;
List<String> raceRoleList = raceFacet.get(id).getListFor(ListKey.MONSTER_ROLES);
if (raceRoleList == null || raceRoleList.isEmpty()) {
raceRoleList = SettingsHandler.getGame().getMonsterRoleDefaultList();
}
// Calculate and add the CR from the PC Classes
for (PCClass pcClass : classFacet.getSet(id)) {
Integer levels = calcClassCR(id, pcClass);
if (levels == null) {
return null;
}
List<String> classRoleList = pcClass.getListFor(ListKey.MONSTER_ROLES);
if (classRoleList != null) {
classRoleList.retainAll(raceRoleList);
if (!classRoleList.isEmpty()) {
levelsKey += levels;
} else {
levelsNonKey += levels;
}
} else {
if (raceRoleList != null) {
levelsNonKey += levels;
} else {
levelsKey += levels;
}
}
}
String sThreshold = SettingsHandler.getGame().getCRThreshold();
if (sThreshold != null) {
threshold = formulaResolvingFacet.resolve(id, FormulaFactory.getFormulaFor(sThreshold), "").intValue();
}
while (levelsNonKey > 1) {
cr++;
// TODO: maybe the divisor 2 should be made configurable,
// or the whole calculation put into a formula
levelsNonKey -= 2;
levelsConverted += 2;
if (levelsConverted >= threshold) {
break;
}
}
if (levelsConverted > 0) {
cr += levelsNonKey;
}
cr += levelsKey;
return cr;
}
use of pcgen.core.PCClass in project pcgen by PCGen.
the class MonsterClassFacet method dataAdded.
/**
* Adds monster classes to the Player Character when a CDOMObject which
* grants monster classes is added to the Player Character.
*
* Triggered when one of the Facets to which MonsterClassFacet listens fires
* a DataFacetChangeEvent to indicate a CDOMObject was added to a Player
* Character.
*
* @param dfce
* The DataFacetChangeEvent containing the information about the
* change
*
* @see pcgen.cdom.facet.event.DataFacetChangeListener#dataAdded(pcgen.cdom.facet.event.DataFacetChangeEvent)
*/
@Override
public void dataAdded(DataFacetChangeEvent<CharID, CDOMObject> dfce) {
CharID id = dfce.getCharID();
CDOMObject cdo = dfce.getCDOMObject();
// Get existing classes
ClassInfo ci = classFacet.removeAllClasses(id);
//
for (int i = levelInfoFacet.getCount(id) - 1; i >= 0; --i) {
PCLevelInfo pli = levelInfoFacet.get(id, i);
final String classKeyName = pli.getClassKeyName();
final PCClass aClass = Globals.getContext().getReferenceContext().silentlyGetConstructedCDOMObject(PCClass.class, classKeyName);
if (aClass.isMonster()) {
levelInfoFacet.remove(id, pli);
}
}
PlayerCharacter pc = trackingFacet.getPC(id);
final List<PCLevelInfo> existingLevelInfo = new ArrayList<>(levelInfoFacet.getSet(id));
levelInfoFacet.removeAll(id);
// Make sure monster classes are added first
if (!pc.isImporting()) {
LevelCommandFactory lcf = cdo.get(ObjectKey.MONSTER_CLASS);
if (lcf != null) {
int levelCount = formulaResolvingFacet.resolve(id, lcf.getLevelCount(), "").intValue();
pc.incrementClassLevel(levelCount, lcf.getPCClass(), true);
}
}
levelInfoFacet.addAll(id, existingLevelInfo);
//
if (!pc.isImporting() && ci != null && !ci.isEmpty()) {
int totalLevels = levelFacet.getTotalLevels(id);
for (PCClass pcClass : ci.getClassSet()) {
//
if (!pcClass.isMonster()) {
classFacet.addClass(id, pcClass);
int cLevels = ci.getLevel(pcClass);
classFacet.setLevel(id, pcClass, cLevels);
pc.setSkillPool(pcClass, 0);
int cMod = 0;
for (int j = 0; j < cLevels; ++j) {
cMod += pc.recalcSkillPointMod(pcClass, ++totalLevels);
}
pc.setSkillPool(pcClass, cMod);
}
}
}
}
use of pcgen.core.PCClass in project pcgen by PCGen.
the class SkillListToCostFacet method dataAdded.
@Override
public void dataAdded(ScopeFacetChangeEvent<CharID, PCClass, ClassSkillList> dfce) {
CharID id = dfce.getCharID();
ClassSkillList skilllist = dfce.getCDOMObject();
Collection<Skill> set = masterSkillFacet.getSet(id.getDatasetID(), skilllist);
if (set != null) {
PCClass pcc = dfce.getScope();
for (Skill s : set) {
add(id, pcc, SkillCost.CLASS, s, skilllist);
}
}
}
use of pcgen.core.PCClass in project pcgen by PCGen.
the class SpellProhibitorFacet method dataAdded.
/**
* Adds the SpellProhibitor objects granted by PCClasses added to the Player
* Character to this SpellProhibitorFacet.
*
* Triggered when one of the Facets to which SpellProhibitorFacet listens
* fires a DataFacetChangeEvent to indicate a PCClass was added to a Player
* Character.
*
* @param dfce
* The DataFacetChangeEvent containing the information about the
* change
*
* @see pcgen.cdom.facet.event.DataFacetChangeListener#dataAdded(pcgen.cdom.facet.event.DataFacetChangeEvent)
*/
@Override
public void dataAdded(DataFacetChangeEvent<CharID, PCClass> dfce) {
PCClass pcc = dfce.getCDOMObject();
CharID id = dfce.getCharID();
Object source = dfce.getSource();
for (SpellProhibitor prohibit : pcc.getSafeListFor(ListKey.PROHIBITED_SPELLS)) {
add(id, pcc, prohibit, source);
}
for (SpellProhibitor prohibit : pcc.getSafeListFor(ListKey.SPELL_PROHIBITOR)) {
add(id, pcc, prohibit, source);
}
}
use of pcgen.core.PCClass in project pcgen by PCGen.
the class PCGVer2Parser method parseSpellLine.
/*
* ###############################################################
* Character Spells Information methods
* ###############################################################
*/
private void parseSpellLine(final String line) {
final PCGTokenizer tokens;
try {
tokens = new PCGTokenizer(line);
} catch (PCGParseException pcgpex) {
final String message = "Illegal Spell line ignored: " + line + Constants.LINE_SEPARATOR + "Error: " + pcgpex.getMessage();
warnings.add(message);
return;
}
Spell aSpell = null;
PCClass aPCClass = null;
PObject source = null;
String spellBook = null;
int times = 1;
int spellLevel = 0;
int numPages = 0;
final List<Ability> metaFeats = new ArrayList<>();
int ppCost = -1;
for (final PCGElement element : tokens.getElements()) {
final String tag = element.getName();
if (IOConstants.TAG_SPELLNAME.equals(tag)) {
String spellName = EntityEncoder.decode(element.getText());
spellName = SpellMigration.getNewSpellKey(spellName, pcgenVersion, SettingsHandler.getGame().getName());
// either NULL (no spell) a Spell instance,
aSpell = Globals.getContext().getReferenceContext().silentlyGetConstructedCDOMObject(Spell.class, spellName);
if (aSpell == null) {
final String message = "Could not find spell named: " + spellName;
warnings.add(message);
return;
}
} else if (IOConstants.TAG_TIMES.equals(tag)) {
try {
times = Integer.parseInt(element.getText());
} catch (NumberFormatException nfe) {
// nothing we can do about it
}
} else if (IOConstants.TAG_CLASS.equals(tag)) {
final String classKey = EntityEncoder.decode(element.getText());
aPCClass = thePC.getClassKeyed(classKey);
if (aPCClass == null) {
final String message = "Invalid class specification: " + classKey;
warnings.add(message);
return;
}
} else if (IOConstants.TAG_SPELL_BOOK.equals(tag)) {
spellBook = EntityEncoder.decode(element.getText());
} else if (IOConstants.TAG_SPELLLEVEL.equals(tag)) {
try {
spellLevel = Integer.parseInt(element.getText());
} catch (NumberFormatException nfe) {
// nothing we can do about it
}
} else if (IOConstants.TAG_SPELLPPCOST.equals(tag)) {
try {
ppCost = Integer.parseInt(element.getText());
} catch (NumberFormatException nfe) {
// nothing we can do about it
}
} else if (IOConstants.TAG_SPELLNUMPAGES.equals(tag)) {
try {
numPages = Integer.parseInt(element.getText());
} catch (NumberFormatException nfe) {
// nothing we can do about it
}
} else if (IOConstants.TAG_SOURCE.equals(tag)) {
String typeName = Constants.EMPTY_STRING;
String objectKey = Constants.EMPTY_STRING;
for (final PCGElement child : element.getChildren()) {
final String childTag = child.getName();
if (IOConstants.TAG_TYPE.equals(childTag)) {
typeName = child.getText().toUpperCase();
} else if (IOConstants.TAG_NAME.equals(childTag)) {
objectKey = child.getText();
}
}
if (IOConstants.TAG_DOMAIN.equals(typeName)) {
Domain domain = Globals.getContext().getReferenceContext().silentlyGetConstructedCDOMObject(DOMAIN_CLASS, objectKey);
ClassSource cs = thePC.getDomainSource(domain);
if (cs == null) {
final String message = "Could not find domain: " + objectKey;
warnings.add(message);
return;
}
source = domain;
} else {
// it's either the class, sub-class or a cast-as class
// first see if it's the class
ClassSpellList csl = Globals.getContext().getReferenceContext().silentlyGetConstructedCDOMObject(ClassSpellList.class, objectKey);
if (((aPCClass != null) && objectKey.equals(aPCClass.getKeyName())) || (aPCClass != null && thePC.getSpellLists(aPCClass).contains(csl))) {
source = aPCClass;
} else {
// see if PC has the class
source = thePC.getClassKeyed(objectKey);
}
}
} else if (IOConstants.TAG_FEATLIST.equals(tag)) {
for (PCGElement child : element.getChildren()) {
final String featKey = EntityEncoder.decode(child.getText());
final Ability anAbility = Globals.getContext().getReferenceContext().silentlyGetConstructedCDOMObject(Ability.class, AbilityCategory.FEAT, featKey);
if (anAbility != null) {
metaFeats.add(anAbility);
}
}
}
}
if ((aPCClass == null) || (spellBook == null)) {
final String message = "Illegal Spell line ignored: " + line;
warnings.add(message);
return;
}
/*
* this can only happen if the source type was NOT DOMAIN!
*/
if (source == null) {
source = aPCClass;
}
// if (obj instanceof List)
// {
// // find the instance of Spell in this class
// // best suited to this spell
// for (final Spell spell : (ArrayList<Spell>) obj)
// {
// // valid spell has a non-negative spell level
// if ((spell != null)
// && (SpellLevel.getFirstLevelForKey(spell,
// thePC.getSpellLists(source), thePC) >= 0))
// {
// aSpell = spell;
// break;
// }
// }
// if (aSpell == null)
// {
// Logging.errorPrint("Could not resolve spell " + obj.toString());
// }
// }
// if (aSpell == null)
// {
// final String message =
// "Could not find spell named: " + String.valueOf(obj);
// warnings.add(message);
//
// return;
// }
// just to make sure the spellbook is present
thePC.addSpellBook(spellBook);
final SpellBook book = thePC.getSpellBookByName(spellBook);
thePC.calculateKnownSpellsForClassLevel(aPCClass);
final Integer[] spellLevels = SpellLevel.levelForKey(aSpell, thePC.getSpellLists(source), thePC);
boolean found = false;
for (int sindex = 0; sindex < spellLevels.length; ++sindex) {
final int level = spellLevels[sindex];
final int metmagicLevels = totalAddedLevelsFromMetamagic(metaFeats);
if (spellLevel > 0 && spellLevel != (level + metmagicLevels)) {
// Skip spell in class lists that does not match level the character knows it.
continue;
}
if (level < 0) {
Collection<CDOMReference<Spell>> mods = source.getListMods(Spell.SPELLS);
if (mods == null) {
continue;
}
for (CDOMReference<Spell> ref : mods) {
Collection<Spell> refSpells = ref.getContainedObjects();
Collection<AssociatedPrereqObject> assocs = source.getListAssociations(Spell.SPELLS, ref);
for (Spell sp : refSpells) {
if (aSpell.getKeyName().equals(sp.getKeyName())) {
for (AssociatedPrereqObject apo : assocs) {
String sb = apo.getAssociation(AssociationKey.SPELLBOOK);
if (spellBook.equals(sb)) {
found = true;
break;
}
}
}
}
}
continue;
}
found = true;
// do not load auto knownspells into default spellbook
if (spellBook.equals(Globals.getDefaultSpellBook()) && thePC.getSpellSupport(aPCClass).isAutoKnownSpell(aSpell, level, false, thePC) && thePC.getAutoSpells()) {
continue;
}
CharacterSpell aCharacterSpell = thePC.getCharacterSpellForSpell(aPCClass, aSpell, source);
// so we'll need to add it to the list
if (aCharacterSpell == null) {
aCharacterSpell = new CharacterSpell(source, aSpell);
aCharacterSpell.addInfo(level, times, spellBook);
thePC.addCharacterSpell(aPCClass, aCharacterSpell);
}
SpellInfo aSpellInfo = null;
if (source.getKeyName().equals(aPCClass.getKeyName()) || !spellBook.equals(Globals.getDefaultSpellBook())) {
aSpellInfo = aCharacterSpell.getSpellInfoFor(spellBook, spellLevel);
// metaFeats list have to do with this?
if ((aSpellInfo == null) || !metaFeats.isEmpty()) {
aSpellInfo = aCharacterSpell.addInfo(spellLevel, times, spellBook);
}
}
if (aSpellInfo != null) {
if (!metaFeats.isEmpty()) {
aSpellInfo.addFeatsToList(metaFeats);
}
aSpellInfo.setActualPPCost(ppCost);
aSpellInfo.setNumPages(numPages);
book.setNumPagesUsed(book.getNumPagesUsed() + numPages);
book.setNumSpells(book.getNumSpells() + 1);
}
}
if (!found) {
final String message = "Could not find spell " + aSpell.getDisplayName() + " in " + shortClassName(source) + " " + source.getDisplayName();
warnings.add(message);
}
}
Aggregations