Search in sources :

Example 1 with CharacterSpell

use of pcgen.core.character.CharacterSpell 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 CharacterSpell

use of pcgen.core.character.CharacterSpell in project pcgen by PCGen.

the class PCGVer2Creator method appendSpellLines.

/*
	 * ###############################################################
	 * Character Spells Information methods
	 * ###############################################################
	 */
/*
	 * #Character Spells Information
	 * CLASS:Wizard|CANCASTPERDAY:2,4(Totals the levels all up + includes attribute bonuses)
	 * SPELLNAME:Blah|SCHOOL:blah|SUBSCHOOL:blah|Etc
	 *
	 * completely changed due to new Spell API
	 */
private void appendSpellLines(StringBuilder buffer) {
    for (PCClass pcClass : charDisplay.getClassSet()) {
        Collection<? extends CharacterSpell> sp = charDisplay.getCharacterSpells(pcClass);
        List<CharacterSpell> classSpells = new ArrayList<>(sp);
        // Add in the spells granted by objects
        thePC.addBonusKnownSpellsToList(pcClass, classSpells);
        Collections.sort(classSpells);
        for (CharacterSpell cSpell : classSpells) {
            for (SpellInfo spellInfo : cSpell.getInfoList()) {
                CDOMObject owner = cSpell.getOwner();
                List<? extends CDOMList<Spell>> lists = charDisplay.getSpellLists(owner);
                if (SpellLevel.getFirstLevelForKey(cSpell.getSpell(), lists, thePC) < 0) {
                    Logging.errorPrint("Ignoring unqualified spell " + cSpell.getSpell() + " in list for class " + pcClass + ".");
                    continue;
                }
                if (spellInfo.getBook().equals(Globals.getDefaultSpellBook()) && thePC.getSpellSupport(pcClass).isAutoKnownSpell(cSpell.getSpell(), SpellLevel.getFirstLevelForKey(cSpell.getSpell(), lists, thePC), false, thePC) && thePC.getAutoSpells()) {
                    continue;
                }
                buffer.append(IOConstants.TAG_SPELLNAME).append(':');
                buffer.append(EntityEncoder.encode(cSpell.getSpell().getKeyName()));
                buffer.append('|');
                buffer.append(IOConstants.TAG_TIMES).append(':');
                buffer.append(spellInfo.getTimes());
                buffer.append('|');
                buffer.append(IOConstants.TAG_CLASS).append(':');
                buffer.append(EntityEncoder.encode(pcClass.getKeyName()));
                buffer.append('|');
                buffer.append(IOConstants.TAG_SPELL_BOOK).append(':');
                buffer.append(EntityEncoder.encode(spellInfo.getBook()));
                buffer.append('|');
                buffer.append(IOConstants.TAG_SPELLLEVEL).append(':');
                buffer.append(spellInfo.getActualLevel());
                if (spellInfo.getNumPages() > 0) {
                    buffer.append('|');
                    buffer.append(IOConstants.TAG_SPELLNUMPAGES).append(':');
                    buffer.append(spellInfo.getNumPages());
                }
                final List<Ability> metaFeats = spellInfo.getFeatList();
                if ((metaFeats != null) && (!metaFeats.isEmpty())) {
                    buffer.append('|');
                    buffer.append(IOConstants.TAG_FEATLIST).append(':');
                    buffer.append('[');
                    String del = Constants.EMPTY_STRING;
                    for (Ability feat : metaFeats) {
                        buffer.append(del);
                        buffer.append(IOConstants.TAG_FEAT).append(':');
                        buffer.append(EntityEncoder.encode(feat.getKeyName()));
                        //$NON-NLS-1$
                        del = "|";
                    }
                    buffer.append(']');
                }
                buffer.append('|');
                appendSourceInTaggedFormat(buffer, StringPClassUtil.getStringFor(owner.getClass()) + "|" + owner.getKeyName());
                buffer.append(IOConstants.LINE_SEP);
            }
        }
    }
}
Also used : Ability(pcgen.core.Ability) CNAbility(pcgen.cdom.content.CNAbility) SpecialAbility(pcgen.core.SpecialAbility) CDOMObject(pcgen.cdom.base.CDOMObject) ArrayList(java.util.ArrayList) CharacterSpell(pcgen.core.character.CharacterSpell) PCClass(pcgen.core.PCClass) Spell(pcgen.core.spell.Spell) CharacterSpell(pcgen.core.character.CharacterSpell) SpellInfo(pcgen.core.character.SpellInfo)

Example 3 with CharacterSpell

use of pcgen.core.character.CharacterSpell in project pcgen by PCGen.

the class PlayerCharacter method calculateKnownSpellsForClassLevel.

public void calculateKnownSpellsForClassLevel(PCClass pcc) {
    if (!pcc.containsListFor(ListKey.KNOWN_SPELLS) || importing || !autoKnownSpells) {
        return;
    }
    // If this class has at least one entry in the "Known spells" tag
    // And we are set up to automatically assign known spells...
    List<? extends CDOMList<Spell>> spellLists = getSpellLists(pcc);
    SpellSupportForPCClass spellSupport = getSpellSupport(pcc);
    // Recalculate the number of spells per day of each level
    // that this chracter can cast in this class.
    spellSupport.calcCastPerDayMapForLevel(this);
    // Get the maximum spell level that this character can cast.
    final int maxCastableLevel = spellSupport.getMaxCastLevel();
    for (CDOMList<Spell> list : spellLists) {
        for (int spellLevel : availSpellFacet.getScopes2(id, list)) {
            if (spellLevel <= maxCastableLevel) {
                for (Spell spell : availSpellFacet.getSet(id, list, spellLevel)) {
                    if (spellSupport.isAutoKnownSpell(spell, spellLevel, true, this)) {
                        CharacterSpell cs = getCharacterSpellForSpell(pcc, spell, pcc);
                        if (cs == null) {
                            // Create a new character spell for this level.
                            cs = new CharacterSpell(pcc, spell);
                            cs.addInfo(spellLevel, 1, Globals.getDefaultSpellBook());
                            addCharacterSpell(pcc, cs);
                        } else {
                            if (cs.getSpellInfoFor(Globals.getDefaultSpellBook(), spellLevel) == null) {
                                cs.addInfo(spellLevel, 1, Globals.getDefaultSpellBook());
                            } else {
                            // already know this one
                            }
                        }
                    }
                }
            }
        }
    }
    for (Domain d : getDomainSet()) {
        if (pcc.getKeyName().equals(getDomainSource(d).getPcclass().getKeyName())) {
            DomainApplication.addSpellsToClassForLevels(this, d, pcc, 0, maxCastableLevel);
        }
    }
}
Also used : CharacterSpell(pcgen.core.character.CharacterSpell) Spell(pcgen.core.spell.Spell) CharacterSpell(pcgen.core.character.CharacterSpell)

Example 4 with CharacterSpell

use of pcgen.core.character.CharacterSpell in project pcgen by PCGen.

the class PlayerCharacter method getCharacterSpells.

/**
	 * Get a list of CharacterSpells from the character spell list.
	 * @param spellSource
	 * @param aSpell
	 * @param book
	 * @param level
	 * @return list of CharacterSpells from the character spell list
	 */
public final List<CharacterSpell> getCharacterSpells(CDOMObject spellSource, final Spell aSpell, final String book, final int level) {
    List<CharacterSpell> csList = new ArrayList<>(getCharacterSpells(spellSource));
    // Add in the spells granted by objects
    addBonusKnownSpellsToList(spellSource, csList);
    final List<CharacterSpell> aList = new ArrayList<>();
    if (csList.isEmpty()) {
        return aList;
    }
    for (CharacterSpell cs : csList) {
        if ((aSpell == null) || cs.getSpell().equals(aSpell)) {
            final SpellInfo si = cs.getSpellInfoFor(book, level, null);
            if (si != null) {
                aList.add(cs);
            }
        }
    }
    return aList;
}
Also used : ArrayList(java.util.ArrayList) CharacterSpell(pcgen.core.character.CharacterSpell) SpellInfo(pcgen.core.character.SpellInfo)

Example 5 with CharacterSpell

use of pcgen.core.character.CharacterSpell in project pcgen by PCGen.

the class PlayerCharacter method getCharacterSpells.

public Collection<CharacterSpell> getCharacterSpells(PObject spellSource, String bookName) {
    List<CharacterSpell> csList = new ArrayList<>(getCharacterSpells(spellSource));
    // Add in the spells granted by objects
    addBonusKnownSpellsToList(spellSource, csList);
    List<CharacterSpell> aList = new ArrayList<>();
    for (CharacterSpell cs : csList) {
        if (cs.hasSpellInfoFor(bookName)) {
            aList.add(cs);
        }
    }
    return aList;
}
Also used : ArrayList(java.util.ArrayList) CharacterSpell(pcgen.core.character.CharacterSpell)

Aggregations

CharacterSpell (pcgen.core.character.CharacterSpell)41 Spell (pcgen.core.spell.Spell)22 ArrayList (java.util.ArrayList)16 PCClass (pcgen.core.PCClass)12 SpellInfo (pcgen.core.character.SpellInfo)12 PObject (pcgen.core.PObject)7 SpellBook (pcgen.core.character.SpellBook)6 Ability (pcgen.core.Ability)5 StringTokenizer (java.util.StringTokenizer)4 CNAbility (pcgen.cdom.content.CNAbility)4 Formula (pcgen.base.formula.Formula)3 CDOMList (pcgen.cdom.base.CDOMList)3 CDOMObject (pcgen.cdom.base.CDOMObject)3 PlayerCharacter (pcgen.core.PlayerCharacter)3 AssociatedPrereqObject (pcgen.cdom.base.AssociatedPrereqObject)2 CDOMReference (pcgen.cdom.base.CDOMReference)2 ClassSource (pcgen.cdom.helper.ClassSource)2 SpellSchool (pcgen.cdom.identifier.SpellSchool)2 ClassSpellList (pcgen.cdom.list.ClassSpellList)2 DomainSpellList (pcgen.cdom.list.DomainSpellList)2