/* * CharacterSpell.java * Copyright 2001 (C) Bryan McRoberts <merton_monk@yahoo.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Created on April 21, 2001, 2:15 PM * * Current Ver: $Revision$ */ package pcgen.core.character; import java.util.ArrayList; import java.util.List; import pcgen.cdom.base.CDOMObject; import pcgen.cdom.base.Constants; import pcgen.cdom.helper.ClassSource; import pcgen.core.Ability; import pcgen.core.Domain; import pcgen.core.PCClass; import pcgen.core.PlayerCharacter; import pcgen.core.Race; import pcgen.core.analysis.SpellCountCalc; import pcgen.core.spell.Spell; /** * {@code PCClass}. * * @author Bryan McRoberts <merton_monk@users.sourceforge.net> */ public final class CharacterSpell implements Comparable<CharacterSpell> { private final List<SpellInfo> infoList = new ArrayList<>(); private final CDOMObject owner; // PCClass/Race/etc. in whose list this object resides private final Spell spell; private String fixedCasterLevel = null; /** * Constructor * @param o * @param aSpell */ public CharacterSpell(final CDOMObject o, final Spell aSpell) { owner = o; spell = aSpell; } /** * Returns index of SpellInfo in infoList, or -1 if it doesn't exist. * * @param pc The character to query. * @param bookName name of spellbook/list * @param level actual level of spell (adjusted by feats) * @param specialty -1 = inSpecialty insensitive;<br>0 = inSpecialty==false; and <br> 1 = inSpecialty==true * @return info index */ public int getInfoIndexFor(PlayerCharacter pc, final String bookName, final int level, final int specialty) { if (infoList.isEmpty()) { return -1; } boolean sp = specialty == 1; if (sp) { sp = isSpecialtySpell(pc); } int i = 0; for (SpellInfo s : infoList) { if (("".equals(bookName) || bookName.equals(s.getBook())) && (level == -1 || s.getActualLevel() == level) && (specialty == -1 || sp)) { return i; } i++; } return -1; } /** * Get info list * @return info list */ public List<SpellInfo> getInfoList() { return infoList; } /** * Get Owner * @return owner */ public CDOMObject getOwner() { return owner; } /** * is speciality spell * @return TRUE if speciality spell */ public boolean isSpecialtySpell(PlayerCharacter pc) { final boolean result; if (spell == null) { result = false; } else if (owner instanceof Domain) { result = true; } else if (owner instanceof PCClass) { final PCClass a = (PCClass) owner; result = SpellCountCalc.isSpecialtySpell(pc, a, spell); } else { result = false; } return result; } /** * Get spell * @return spell */ public Spell getSpell() { return spell; } /** * Get the spell info * @param bookName * @param level * @return SpellInfo */ public SpellInfo getSpellInfoFor(final String bookName, final int level) { return getSpellInfoFor(bookName, level, null); } /** * Get the Spell info * @param bookName * @param level * @param featList * @return Spell Info */ public SpellInfo getSpellInfoFor(final String bookName, final int level, final List<Ability> featList) { if (infoList.isEmpty()) { return null; } for (SpellInfo s : infoList) { if (("".equals(bookName) || bookName.equals(s.getBook())) && (level == -1 || s.getActualLevel() == level) && (featList == null || featList.isEmpty() && (s.getFeatList() == null || s .getFeatList().isEmpty()) || s.getFeatList() != null && featList.toString() .equals(s.getFeatList().toString()))) { return s; } } return null; } public boolean hasSpellInfoFor(int level) { if (infoList.isEmpty()) { return false; } for (SpellInfo s : infoList) { if (s.getActualLevel() == level) { return true; } } return false; } public boolean hasSpellInfoFor(String bookName) { if (infoList.isEmpty()) { return false; } for (SpellInfo s : infoList) { if (bookName.equals(s.getBook())) { return true; } } return false; } /** * Add Spell info * @param level * @param times * @param book * @return SpellInfo */ public SpellInfo addInfo(final int level, final int times, final String book) { return addInfo(level, level, times, book, null); } /** * Add Spell info * @param level * @param times * @param book * @param featList * @return SpellInfo */ public SpellInfo addInfo(final int origLevel, final int level, final int times, final String book, final List<Ability> featList) { final SpellInfo si = new SpellInfo(this, origLevel, level, times, book); if (featList != null) { si.addFeatsToList(featList); } infoList.add(si); return si; } /** * Compares with another object. The implementation compares the CharacterSpell's contained spell object with the * passed-in CharacterSpell's spell object. * * @param obj the CharacterSpell to compare with * @return a negative integer, zero, or a positive integer as this object * is less than, equal to, or greater than the specified object. * @see Comparable#compareTo(Object) */ @Override public int compareTo(final CharacterSpell obj) { int compare = spell.compareTo(obj.spell); if (compare == 0) { if (fixedCasterLevel == null) { if (obj.fixedCasterLevel != null) { compare = -1; } } else if (obj.fixedCasterLevel == null) { compare = 1; } else { compare = fixedCasterLevel.compareTo(obj.fixedCasterLevel); } } if (compare == 0) { compare = owner.getClass().toString().compareTo(obj.owner.getClass().toString()); } if (compare == 0) { compare = owner.getKeyName().compareTo(obj.owner.getKeyName()); } if (compare == 0) { int thisILsize = infoList.size(); int otherILsize = obj.infoList.size(); if (thisILsize < otherILsize) { compare = -1; } else if (thisILsize > otherILsize) { compare = 1; } else { //compare contents... for (int i = 0; i < thisILsize; i++) { compare = infoList.get(i).compareTo(obj.infoList.get(i)); if (compare != 0) { break; } } } } return compare; } /** * returns true if * obj.getName() equals this.getName() * or obj == this * @param obj * @return true if equal */ @Override public boolean equals(final Object obj) { return obj != null && obj instanceof CharacterSpell && ((CharacterSpell) obj).getName().equals(getName()); } /** * this method is used the same as equals() but for hash tables * @return hash code */ @Override public int hashCode() { return toString().hashCode(); } /** * Remove spell info * @param x */ public void removeSpellInfo(final SpellInfo x) { if (x != null) { infoList.remove(x); } } /////////////////////////////////////////////////////////////////////// // Accessor(s) and Mutator(s) /////////////////////////////////////////////////////////////////////// /** * Returns the Spell's Name for Tree's display * * @return the Spell's Name for Tree's display */ @Override public String toString() { final String result; if (spell == null) { result = ""; } else { result = spell.getDisplayName(); } return result; } /** * Returns the name of the spell for this Character Spell * @return name */ private String getName() { final StringBuilder buf = new StringBuilder(owner.toString()); if (spell != null) { buf.append(':').append(spell.getDisplayName()); } return buf.toString(); } /** * @return Returns the fixedCasterLevel. */ public String getFixedCasterLevel() { return fixedCasterLevel; } /** * @param fixedCasterLevel The fixedCasterLevel to set. */ public void setFixedCasterLevel(final String fixedCasterLevel) { this.fixedCasterLevel = fixedCasterLevel; } public String getVariableSource(PlayerCharacter pc) { if (owner instanceof Domain) { ClassSource source = pc.getDomainSource((Domain) owner); if (source != null) { return "CLASS:" + pc.getClassKeyed(source.getPcclass().getKeyName()); } } else if (owner instanceof PCClass) { return "CLASS:" + owner.getKeyName(); } else if (owner instanceof Race) // could be innate spell for race { return "RACE:" + owner.getKeyName(); } return Constants.EMPTY_STRING; } }