Search in sources :

Example 1 with PObject

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);
    }
}
Also used : ArrayList(java.util.ArrayList) Spell(pcgen.core.spell.Spell) CharacterSpell(pcgen.core.character.CharacterSpell) ClassSource(pcgen.cdom.helper.ClassSource) AssociatedPrereqObject(pcgen.cdom.base.AssociatedPrereqObject) CNAbility(pcgen.cdom.content.CNAbility) Ability(pcgen.core.Ability) SpecialAbility(pcgen.core.SpecialAbility) ClassSpellList(pcgen.cdom.list.ClassSpellList) PCClass(pcgen.core.PCClass) SpellBook(pcgen.core.character.SpellBook) PObject(pcgen.core.PObject) CharacterSpell(pcgen.core.character.CharacterSpell) Domain(pcgen.core.Domain) CDOMReference(pcgen.cdom.base.CDOMReference) SpellInfo(pcgen.core.character.SpellInfo)

Example 2 with PObject

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;
}
Also used : PObject(pcgen.core.PObject) BaseKit(pcgen.core.kit.BaseKit) Kit(pcgen.core.Kit) BigDecimal(java.math.BigDecimal)

Example 3 with PObject

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());
        }
    }
}
Also used : SpellBook(pcgen.core.character.SpellBook) PObject(pcgen.core.PObject) ArrayList(java.util.ArrayList) PCClass(pcgen.core.PCClass) SpellSupportForPCClass(pcgen.core.SpellSupportForPCClass)

Example 4 with PObject

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;
        }
    }
}
Also used : Ability(pcgen.core.Ability) ArrayList(java.util.ArrayList) CDOMSingleRef(pcgen.cdom.reference.CDOMSingleRef) Spell(pcgen.core.spell.Spell) CharacterSpell(pcgen.core.character.CharacterSpell) PObject(pcgen.core.PObject) CharacterSpell(pcgen.core.character.CharacterSpell) Domain(pcgen.core.Domain)

Example 5 with PObject

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());
    }
}
Also used : PersistenceLayerException(pcgen.persistence.PersistenceLayerException) BonusObj(pcgen.core.bonus.BonusObj) PObject(pcgen.core.PObject) TransitionChoice(pcgen.cdom.base.TransitionChoice)

Aggregations

PObject (pcgen.core.PObject)15 CharacterSpell (pcgen.core.character.CharacterSpell)7 ArrayList (java.util.ArrayList)6 Spell (pcgen.core.spell.Spell)5 PCClass (pcgen.core.PCClass)4 Ability (pcgen.core.Ability)3 Domain (pcgen.core.Domain)3 SpellInfo (pcgen.core.character.SpellInfo)3 StringTokenizer (java.util.StringTokenizer)2 SpellBook (pcgen.core.character.SpellBook)2 InfoFacade (pcgen.facade.core.InfoFacade)2 BigDecimal (java.math.BigDecimal)1 List (java.util.List)1 HashMapToList (pcgen.base.util.HashMapToList)1 AssociatedPrereqObject (pcgen.cdom.base.AssociatedPrereqObject)1 CDOMList (pcgen.cdom.base.CDOMList)1 CDOMReference (pcgen.cdom.base.CDOMReference)1 TransitionChoice (pcgen.cdom.base.TransitionChoice)1 CNAbility (pcgen.cdom.content.CNAbility)1 AvailableSpell (pcgen.cdom.helper.AvailableSpell)1