use of pcgen.core.PObject 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);
}
}
use of pcgen.core.PObject in project pcgen by PCGen.
the class CharacterFacadeImpl method isQualifiedFor.
/**
* @see pcgen.core.facade.CharacterFacade#isQualifiedFor(pcgen.core.facade.InfoFacade)
*/
@Override
public boolean isQualifiedFor(InfoFacade infoFacade) {
if (!(infoFacade instanceof PObject)) {
return false;
}
PObject pObj = (PObject) infoFacade;
if (!theCharacter.isQualified(pObj)) {
return false;
}
if (infoFacade instanceof Kit) {
Kit kit = (Kit) infoFacade;
BigDecimal totalCost = kit.getTotalCostToBeCharged(theCharacter);
if (totalCost != null) {
if (theCharacter.getGold().compareTo(totalCost) < 0) {
// Character cannto afford the kit
return false;
}
}
}
return true;
}
use of pcgen.core.PObject in project pcgen by PCGen.
the class SpellSupportFacadeImpl method buildKnownPreparedNodes.
/**
* Construct the list of spells the character knows, has prepared or has in
* a spell book.
*/
private void buildKnownPreparedNodes() {
allKnownSpellNodes.clearContents();
knownSpellNodes.clearContents();
bookSpellNodes.clearContents();
preparedSpellNodes.clearContents();
// Ensure spell information is up to date
pc.getSpellList();
// Scan character classes for spell classes
List<PCClass> classList = getCharactersSpellcastingClasses();
List<PObject> pobjList = new ArrayList<>(classList);
// Include spells from race etc
pobjList.add(charDisplay.getRace());
// Look at each spell on each spellcasting class
for (PObject pcClass : pobjList) {
buildKnownPreparedSpellsForCDOMObject(pcClass);
}
spellBooks.clear();
spellBookNames.clearContents();
for (SpellBook spellBook : charDisplay.getSpellBooks()) {
if (spellBook.getType() == SpellBook.TYPE_PREPARED_LIST) {
DummySpellNodeImpl spellListNode = new DummySpellNodeImpl(getRootNode(spellBook.getName()));
preparedSpellLists.add(spellListNode);
addDummyNodeIfSpellListEmpty(spellBook.getName());
} else if (spellBook.getType() == SpellBook.TYPE_SPELL_BOOK) {
DummySpellNodeImpl spellListNode = new DummySpellNodeImpl(getRootNode(spellBook.getName()));
spellBooks.add(spellListNode);
addDummyNodeIfSpellBookEmpty(spellBook.getName());
spellBookNames.addElement(spellBook.getName());
}
}
}
use of pcgen.core.PObject in project pcgen by PCGen.
the class KitSpells method updatePCSpells.
/**
* Add spells from this Kit to the PC
*
* @param pc The PC to add the spells to
* @param aSpell A Spell to add to the PC
* @param pcClass The class instance the spells are to be added to.
*/
private void updatePCSpells(final PlayerCharacter pc, final KitSpellBookEntry aSpell, final PCClass pcClass) {
Spell spell = aSpell.getSpell();
int spLevel = 99;
// Check to see if we have any domains that have this spell.
PObject owner = null;
if (pc.hasDomains()) {
for (Domain domain : pc.getDomainSet()) {
List<? extends CDOMList<Spell>> lists = pc.getSpellLists(domain);
int newLevel = SpellLevel.getFirstLevelForKey(spell, lists, pc);
if (newLevel > 0 && newLevel < spLevel) {
spLevel = newLevel;
owner = domain;
}
}
}
if (spLevel == 99) {
spLevel = SpellLevel.getFirstLevelForKey(spell, pc.getSpellLists(pcClass), pc);
owner = pcClass;
}
if (spLevel < 0) {
Logging.errorPrint("SPELLS: " + pcClass.getDisplayName() + " cannot cast spell \"" + spell.getKeyName() + "\"");
return;
}
final CharacterSpell cs = new CharacterSpell(owner, spell);
final List<CDOMSingleRef<Ability>> modifierList = aSpell.getModifiers();
int adjustedLevel = spLevel;
List<Ability> metamagicFeatList = new ArrayList<>();
for (CDOMSingleRef<Ability> feat : modifierList) {
Ability anAbility = feat.get();
adjustedLevel += anAbility.getSafe(IntegerKey.ADD_SPELL_LEVEL);
metamagicFeatList.add(anAbility);
}
if (metamagicFeatList.size() <= 0) {
metamagicFeatList = null;
}
if (!pc.hasSpellBook(aSpell.getBookName())) {
pc.addSpellBook(aSpell.getBookName());
}
for (int numTimes = 0; numTimes < aSpell.getCopies(); numTimes++) {
final String aString = pc.addSpell(cs, metamagicFeatList, pcClass.getKeyName(), aSpell.getBookName(), adjustedLevel, spLevel);
if (!aString.isEmpty()) {
Logging.errorPrint("Add spell failed:" + aString);
return;
}
}
}
use of pcgen.core.PObject in project pcgen by PCGen.
the class BioSetLoader method parseTokens.
private void parseTokens(LoadContext context, AgeSet ageSet, StringTokenizer tok) {
final PObject dummy = new PObject();
try {
while (tok.hasMoreTokens()) {
// in the code below, I use "new String()" to unlink the string from the containing file to save memory,
// but I don't intern() the string because it's not fully parsed yet so don't want to add permgen overhead
// to a string that's just going to get GC'd eventually
//
// This pessimization might be removable if we get all impls of CDOMToken.parseToken() to intern. But right
// now there are too many of them...
String currentTok = tok.nextToken();
if (currentTok.startsWith("BONUS:")) {
if (context.processToken(dummy, "BONUS", new String(currentTok.substring(6)))) {
context.commit();
} else {
context.rollback();
Logging.errorPrint("Error in BONUS parse: " + currentTok);
Logging.replayParsedMessages();
}
} else if (currentTok.startsWith("KIT:")) {
if (context.processToken(dummy, "KIT", new String(currentTok.substring(4)))) {
context.commit();
} else {
context.rollback();
Logging.errorPrint("Error in KIT parse: " + currentTok);
Logging.replayParsedMessages();
}
} else {
Logging.errorPrint("Unexpected token in AGESET: " + currentTok);
}
}
List<BonusObj> bonuses = dummy.getListFor(ListKey.BONUS);
if (bonuses != null) {
ageSet.addBonuses(bonuses);
}
List<TransitionChoice<Kit>> kits = dummy.getListFor(ListKey.KIT_CHOICE);
if (kits != null) {
ageSet.addKits(kits);
}
} catch (PersistenceLayerException e) {
Logging.errorPrint("Error in token parse: " + e.getLocalizedMessage());
}
}
Aggregations