/** Construct the list of available spells for the character. */
  private void buildAvailableNodes() {
    availableSpellNodes.clearContents();
    // Scan character classes for spell classes
    List<PCClass> classList = getCharactersSpellcastingClasses();

    // Look at each spell on each spellcasting class
    for (PCClass pcClass : classList) {
      DoubleKeyMapToList<SpellFacade, String, SpellNode> existingSpells =
          buildExistingSpellMap(availableSpellNodes, pcClass);

      for (Spell spell : pc.getAllSpellsInLists(charDisplay.getSpellLists(pcClass))) {
        // Create SpellNodeImpl for each spell
        CharacterSpell charSpell = new CharacterSpell(pcClass, spell);
        SpellFacadeImplem spellImplem = new SpellFacadeImplem(pc, spell, charSpell, null);

        HashMapToList<CDOMList<Spell>, Integer> levelInfo = pc.getSpellLevelInfo(spell);

        for (CDOMList<Spell> spellList : charDisplay.getSpellLists(pcClass)) {
          List<Integer> levels = levelInfo.getListFor(spellList);
          if (levels != null) {
            for (Integer level : levels) {
              SpellNodeImpl node =
                  new SpellNodeImpl(spellImplem, pcClass, String.valueOf(level), null);
              if (!existingSpells.containsInList(spellImplem, node.getSpellLevel(), node)) {
                // Add to list
                availableSpellNodes.addElement(node);
              }
            }
          }
        }
      }
    }
  }
 /* (non-Javadoc)
  * @see pcgen.core.facade.SpellSupportFacade#addKnownSpell(pcgen.core.facade.SpellSupportFacade.SpellNode)
  */
 @Override
 public void addKnownSpell(SpellNode spell) {
   SpellNode node = addSpellToCharacter(spell, Globals.getDefaultSpellBook(), new ArrayList<>());
   if (node != null) {
     allKnownSpellNodes.addElement(node);
     knownSpellNodes.addElement(node);
     if (!StringUtils.isEmpty(charDisplay.getSpellBookNameToAutoAddKnown())) {
       addToSpellBook(node, charDisplay.getSpellBookNameToAutoAddKnown());
     }
   }
   updateSpellsTodo();
   pcFacade.refreshAvailableTempBonuses();
 }
Beispiel #3
0
  /* (non-Javadoc)
   * @see pcgen.core.prereq.PrerequisiteTest#passes(pcgen.core.PlayerCharacter)
   */
  @Override
  public int passes(final Prerequisite prereq, final CharacterDisplay display, CDOMObject source) {

    //
    // If game mode doesn't support alignment, then pass the prereq
    //
    int runningTotal = 0;

    if (Globals.getGameModeAlignmentText().length() == 0) {
      runningTotal = 1;
    } else {
      CDOMSingleRef<PCAlignment> deityAlign = null; // $NON-NLS-1$
      Deity deity = display.getDeity();
      if (deity != null) {
        deityAlign = deity.get(ObjectKey.ALIGNMENT);
      }
      if (deityAlign != null) {
        String desiredAlignIdentifier = prereq.getOperand();
        PCAlignment desiredAlign = getPCAlignment(desiredAlignIdentifier);

        if (desiredAlign.equals(deityAlign.get())) {
          runningTotal = 1;
        }
      }
    }

    return countedTotal(prereq, runningTotal);
  }
  /**
   * Create a new instance of SpellSupportFacadeImpl to manage the display and update of a
   * character's spells.
   *
   * @param pc The character we are managing.
   * @param delegate The delegate class for UI display.
   * @param dataSet The current data being used.
   * @param todoManager The user tasks tracker.
   * @param pcFacade The character facade.
   */
  public SpellSupportFacadeImpl(
      PlayerCharacter pc,
      UIDelegate delegate,
      DataSetFacade dataSet,
      TodoManager todoManager,
      CharacterFacadeImpl pcFacade) {
    this.pc = pc;
    this.infoFactory = pcFacade.getInfoFactory();
    this.charDisplay = pc.getDisplay();
    this.delegate = delegate;
    this.dataSet = dataSet;
    this.todoManager = todoManager;
    this.pcFacade = pcFacade;
    rootNodeMap = new HashMap<>();

    spellBookNames = new DefaultListFacade<>();
    defaultSpellBook = new DefaultReferenceFacade<>(charDisplay.getSpellBookNameToAutoAddKnown());

    availableSpellNodes = new DefaultListFacade<>();
    buildAvailableNodes();
    allKnownSpellNodes = new DefaultListFacade<>();
    knownSpellNodes = new DefaultListFacade<>();
    preparedSpellNodes = new DefaultListFacade<>();
    bookSpellNodes = new DefaultListFacade<>();
    preparedSpellLists = new ArrayList<>();
    spellBooks = new ArrayList<>();
    buildKnownPreparedNodes();

    updateSpellsTodo();
  }
Beispiel #5
0
  /**
   * Get the LOAD sub token
   *
   * @param display
   * @return the LOAD sub token
   */
  public static String getLoadToken(CharacterDisplay display) {
    Load load = display.getLoadType();

    switch (load) {
      case LIGHT:
        return CoreUtility.capitalizeFirstLetter(Load.LIGHT.toString());

      case MEDIUM:
        return CoreUtility.capitalizeFirstLetter(Load.MEDIUM.toString());

      case HEAVY:
        return CoreUtility.capitalizeFirstLetter(Load.HEAVY.toString());

      case OVERLOAD:
        return CoreUtility.capitalizeFirstLetter(Load.OVERLOAD.toString());

      default:
        Logging.errorPrint(
            "Unknown load constant detected in TokenTotal.getLoadToken, the constant was "
                + load
                + ".");

        return "Unknown";
    }
  }
  private void buildKnownPreparedSpellsForCDOMObject(CDOMObject pObject) {
    Collection<? extends CharacterSpell> sp = charDisplay.getCharacterSpells(pObject);
    List<CharacterSpell> cSpells = new ArrayList<>(sp);

    // Add in the spells granted by objects
    pc.addBonusKnownSpellsToList(pObject, cSpells);
    PCClass pcClass = (PCClass) (pObject instanceof PCClass ? pObject : null);

    for (CharacterSpell charSpell : cSpells) {
      for (SpellInfo spellInfo : charSpell.getInfoList()) {
        // Create SpellNodeImpl for each spell
        String book = spellInfo.getBook();
        boolean isKnown = Globals.getDefaultSpellBook().equals(book);
        SpellFacadeImplem spellImplem =
            new SpellFacadeImplem(pc, charSpell.getSpell(), charSpell, spellInfo);
        SpellNodeImpl node;
        if (pcClass != null) {
          node =
              new SpellNodeImpl(
                  spellImplem,
                  pcClass,
                  String.valueOf(spellInfo.getActualLevel()),
                  getRootNode(book));
        } else {
          node =
              new SpellNodeImpl(
                  spellImplem, String.valueOf(spellInfo.getActualLevel()), getRootNode(book));
        }
        if (spellInfo.getTimes() > 1) {
          node.addCount(spellInfo.getTimes() - 1);
        }
        boolean isSpellBook =
            charDisplay.getSpellBookByName(book).getType() == SpellBook.TYPE_SPELL_BOOK;
        // Add to list
        if (isKnown) {
          allKnownSpellNodes.addElement(node);
          knownSpellNodes.addElement(node);
        } else if (isSpellBook) {
          bookSpellNodes.addElement(node);
        } else if (pObject instanceof Race) {
          allKnownSpellNodes.addElement(node);
        } else {
          preparedSpellNodes.addElement(node);
        }
      }
    }
  }
  /**
   * Set the spell book to hold any new known spells.
   *
   * @param bookName The name of the new default spell book.
   */
  @Override
  public void setDefaultSpellBook(String bookName) {
    SpellBook book = charDisplay.getSpellBookByName(bookName);
    if (book == null || book.getType() != SpellBook.TYPE_SPELL_BOOK) {
      return;
    }

    pc.setSpellBookNameToAutoAddKnown(bookName);
    defaultSpellBook.set(bookName);
  }
 @Override
 public void setBonus(int bonus) {
   String initiativeVar =
       ControlUtilities.getControlToken(Globals.getContext(), CControl.INITIATIVE);
   if (initiativeVar == null) {
     this.incrementalBonus = bonus - display.processOldInitiativeMod();
   } else {
     this.incrementalBonus = bonus - ((Number) pc.getGlobal(initiativeVar)).intValue();
   }
   setCurrentInitiative(roll + getModifier() + mod);
 }
Beispiel #9
0
  /**
   * Get FOLLOWERLIST Token
   *
   * @param display The character to be queried
   * @return The list of followers.
   */
  public static String getFollowerListToken(CharacterDisplay display) {
    StringBuilder buf = new StringBuilder();

    boolean needComma = false;

    for (Follower aF : display.getFollowerList()) {
      for (PlayerCharacter nPC : Globals.getPCList()) {
        CharacterDisplay nDisplay = nPC.getDisplay();
        if (aF.getFileName().equals(nDisplay.getFileName())) {
          if (needComma) {
            buf.append(", ");
          }

          buf.append(FileAccess.filterString(nDisplay.getName()));
          needComma = true;
        }
      }
    }

    return buf.toString();
  }
  private List<PCClass> getCharactersSpellcastingClasses() {
    List<PCClass> castingClasses = new ArrayList<>();
    Collection<PCClass> classes = charDisplay.getClassSet();
    for (PCClass pcClass : classes) {
      if (pcClass.get(FactKey.valueOf("SpellType")) != null) {
        SpellSupportForPCClass spellSupport = pc.getSpellSupport(pcClass);
        if (spellSupport.canCastSpells(pc) || spellSupport.hasKnownList()) {
          castingClasses.add(pcClass);
        }
      }
    }

    return castingClasses;
  }
Beispiel #11
0
  /**
   * Get a pipe separated list of creature types for this PC (defaults to humanoid).
   *
   * @return the list of types
   */
  @Deprecated
  public static String getCritterType(CharacterDisplay display) {
    final StringBuilder critterType = new StringBuilder();

    // Not too sure about this if, but that's what the previous code
    // implied...
    Race race = display.getRace();
    if (race != null) {
      critterType.append(race.getType());
    } else {
      critterType.append("Humanoid");
    }

    for (PCTemplate t : display.getTemplateSet()) {
      final String aType = t.getType();

      if (!"".equals(aType)) {
        critterType.append('|').append(aType);
      }
    }

    return critterType.toString();
  }
Beispiel #12
0
  /* (non-Javadoc)
   * @see pcgen.core.prereq.PrerequisiteTest#passes(pcgen.core.PlayerCharacter)
   */
  @Override
  public int passes(final Prerequisite prereq, final CharacterDisplay display, CDOMObject source)
      throws PrerequisiteException {
    int runningTotal;
    try {
      final int targetHands = Integer.parseInt(prereq.getOperand());

      runningTotal = prereq.getOperator().compare(display.getHands(), targetHands);
    } catch (NumberFormatException nfe) {
      throw new PrerequisiteException(
          LanguageBundle.getFormattedString(
              "PreHands.error.badly_formed", prereq.getOperand())); // $NON-NLS-1$
    }
    return countedTotal(prereq, runningTotal);
  }
  /** 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());
      }
    }
  }
 @Override
 public int getBonus() {
   String initiativeVar =
       ControlUtilities.getControlToken(Globals.getContext(), CControl.INITIATIVE);
   String initiativeStatVar =
       ControlUtilities.getControlToken(Globals.getContext(), CControl.INITIATIVESTAT);
   if (initiativeVar == null) {
     PCStat dex =
         Globals.getContext()
             .getReferenceContext()
             .silentlyGetConstructedCDOMObject(PCStat.class, "DEX");
     return display.processOldInitiativeMod() - pc.getStatModFor(dex) + incrementalBonus;
   }
   return ((Number) pc.getGlobal(initiativeVar)).intValue()
       - ((Number) pc.getGlobal(initiativeStatVar)).intValue()
       + incrementalBonus;
 }
  private RootNodeImpl getRootNode(String bookName) {
    if (Globals.getDefaultSpellBook().equals(bookName)) {
      return null;
    }

    RootNodeImpl rootNode = rootNodeMap.get(bookName);
    if (rootNode == null) {
      SpellBook book = charDisplay.getSpellBookByName(bookName);
      if (book == null) {
        return null;
      }

      rootNode = new RootNodeImpl(book);
      rootNodeMap.put(bookName, rootNode);
    }

    return rootNode;
  }
Beispiel #16
0
  /*
   * (non-Javadoc)
   *
   * @see
   * pcgen.core.prereq.PrerequisiteTest#passes(pcgen.core.PlayerCharacter)
   */
  @Override
  public int passes(final Prerequisite prereq, final CharacterDisplay display, CDOMObject source) {
    final int reqnumber = Integer.parseInt(prereq.getOperand());
    final String requiredRaceType = prereq.getKey();
    int runningTotal = 0;

    try {
      RaceType preRaceType = RaceType.valueOf(requiredRaceType);
      if (preRaceType.equals(display.getRace().get(ObjectKey.RACETYPE))) {
        runningTotal++;
      }
    } catch (IllegalArgumentException e) {
      // Can't match
    }
    if (getCritterType(display).indexOf(requiredRaceType) >= 0) {
      runningTotal++;
    }
    runningTotal = prereq.getOperator().compare(runningTotal, reqnumber);
    return countedTotal(prereq, runningTotal);
  }
  private void updateSpellsTodo() {
    boolean hasFree = false;
    for (PCClass aClass : charDisplay.getClassSet()) {
      if (pc.getSpellSupport(aClass).hasKnownList()
          || pc.getSpellSupport(aClass).hasKnownSpells(pc)) {
        int highestSpellLevel = pc.getSpellSupport(aClass).getHighestLevelSpell(pc);
        for (int i = 0; i <= highestSpellLevel; ++i) {
          if (pc.availableSpells(i, aClass, Globals.getDefaultSpellBook(), true, false)
              || pc.availableSpells(i, aClass, Globals.getDefaultSpellBook(), true, true)) {
            hasFree = true;
            break;
          }
        }
      }
    }

    if (hasFree) {
      todoManager.addTodo(new TodoFacadeImpl(Tab.SPELLS, "Known", "in_splTodoRemain", 120));
    } else {
      todoManager.removeTodo("in_splTodoRemain");
    }
  }
 @Override
 public Float resolve(CharacterDisplay display) {
   String CompString = display.getSafeStringFor(StringKey.MISC_COMPANIONS);
   List<String> companions = Arrays.asList(CompString.split("\r?\n"));
   return (float) companions.size();
 }
  @Override
  public void exportSpells() {
    final String template =
        PCGenSettings.getInstance().getProperty(PCGenSettings.SELECTED_SPELL_SHEET_PATH);
    if (StringUtils.isEmpty(template)) {
      delegate.showErrorMessage(
          Constants.APPLICATION_NAME, LanguageBundle.getString("in_spellNoSheet")); // $NON-NLS-1$
      return;
    }
    String ext = template.substring(template.lastIndexOf('.'));

    // Get the name of the file to output to.
    JFileChooser fcExport = new JFileChooser();
    fcExport.setCurrentDirectory(new File(PCGenSettings.getPcgDir()));
    fcExport.setDialogTitle(
        LanguageBundle.getString("InfoSpells.export.spells.for")
            + charDisplay.getDisplayName()); // $NON-NLS-1$

    if (fcExport.showSaveDialog(null) != JFileChooser.APPROVE_OPTION) {
      return;
    }
    final String aFileName = fcExport.getSelectedFile().getAbsolutePath();
    if (aFileName.length() < 1) {
      delegate.showErrorMessage(
          Constants.APPLICATION_NAME,
          LanguageBundle.getString("InfoSpells.must.set.filename")); // $NON-NLS-1$
      return;
    }

    try {
      final File outFile = new File(aFileName);

      if (outFile.isDirectory()) {
        delegate.showErrorMessage(
            Constants.APPLICATION_NAME,
            LanguageBundle.getString("InfoSpells.can.not.overwrite.directory")); // $NON-NLS-1$
        return;
      }

      if (outFile.exists()) {
        int reallyClose =
            JOptionPane.showConfirmDialog(
                null,
                LanguageBundle.getFormattedString(
                    "InfoSpells.confirm.overwrite", outFile.getName()), // $NON-NLS-1$
                LanguageBundle.getFormattedString("InfoSpells.overwriting", outFile.getName()),
                JOptionPane.YES_NO_OPTION); // $NON-NLS-1$

        if (reallyClose != JOptionPane.YES_OPTION) {
          return;
        }
      }

      // Output the file
      File templateFile = new File(template);
      boolean success;
      if (ExportUtilities.isPdfTemplate(templateFile)) {
        success = BatchExporter.exportCharacterToPDF(pcFacade, outFile, templateFile);
      } else {
        success = BatchExporter.exportCharacterToNonPDF(pcFacade, outFile, templateFile);
      }

      if (!success) {
        delegate.showErrorMessage(
            Constants.APPLICATION_NAME,
            LanguageBundle.getFormattedString(
                "InfoSpells.export.failed", charDisplay.getDisplayName())); // $NON-NLS-1$
      }
    } catch (Exception ex) {
      Logging.errorPrint(
          LanguageBundle.getFormattedString(
              "InfoSpells.export.failed", charDisplay.getDisplayName()),
          ex); //$NON-NLS-1$
      delegate.showErrorMessage(
          Constants.APPLICATION_NAME,
          LanguageBundle.getFormattedString(
              "InfoSpells.export.failed.retry", charDisplay.getDisplayName())); // $NON-NLS-1$
    }
  }
Beispiel #20
0
 /**
  * Get the CAPACITY sub token
  *
  * @param display
  * @return the CAPACITY sub token
  */
 public static String getCapacityToken(CharacterDisplay display) {
   return Globals.getGameModeUnitSet().displayWeightInUnitSet(display.getMaxLoad().doubleValue());
 }
Beispiel #21
0
 /**
  * Get the WEIGHT sub token
  *
  * @param display
  * @return the WEIGHT sub token
  */
 public static String getWeightToken(CharacterDisplay display) {
   return Globals.getGameModeUnitSet().displayWeightInUnitSet(display.totalWeight().doubleValue())
       + Globals.getGameModeUnitSet().getWeightUnit();
 }
Beispiel #22
0
  private static String _writeArmorProperty(Equipment eq, String property, PlayerCharacter aPC) {
    CharacterDisplay display = aPC.getDisplay();
    StringBuilder ret = new StringBuilder();

    if (property.startsWith("NAME")) {
      if (eq.isEquipped() && !property.equals("NAMENOSTAR")) {
        ret.append("*");
      }

      ret.append(OutputNameFormatting.parseOutputName(eq, aPC));
      ret.append(eq.getAppliedName());
    } else if (property.startsWith("OUTPUTNAME")) {
      // TODO this appears to be the same as above.  Should be refactored
      if (eq.isEquipped()) {
        ret.append("*");
      }

      ret.append(OutputNameFormatting.parseOutputName(eq, aPC));
      ret.append(eq.getAppliedName());
    } else if (property.startsWith("TOTALAC") || property.startsWith("ACBONUS")) {
      // adjustments for new equipment modifier
      // EQMARMOR|AC|x|TYPE=ENHANCEMENT changed to COMBAT|AC|x|TYPE=Armor.ENHANCEMENT
      // FileAccess.write(output, Delta.toString(eq.getACMod()));
      String acMod = aPC.getControl(CControl.EQACMOD);
      if (acMod != null) {
        Object o = aPC.getLocal(eq, acMod);
        int intValue = ((Number) o).intValue();
        ret.append(Delta.toString(intValue));
      } else {
        ret.append(Delta.toString((int) eq.bonusTo(aPC, "COMBAT", "AC", true)));
      }
    } else if (property.startsWith("BASEAC")) {
      // adjustments for new equipment modifier
      // EQMARMOR|AC|x|TYPE=ENHANCEMENT changed to COMBAT|AC|x|TYPE=Armor.ENHANCEMENT
      // FileAccess.write(output, Delta.toString(eq.getACMod()));
      String baseMod = aPC.getControl(CControl.EQBASEACMOD);
      if (baseMod != null) {
        Object o = aPC.getLocal(eq, baseMod);
        int intValue = ((Number) o).intValue();
        ret.append(Delta.toString(intValue));
      } else {
        ret.append(Delta.toString((int) BonusCalc.charBonusTo(eq, "COMBAT", "AC", aPC)));
      }
    } else if (property.startsWith("MAXDEX")) {
      final int iMax = EqToken.getMaxDexTokenInt(aPC, eq);
      if (iMax != Constants.MAX_MAXDEX) {
        ret.append(Delta.toString(iMax));
      }
    } else if (property.startsWith("ACCHECK")) {
      ret.append(Delta.toString(EqToken.getAcCheckTokenInt(aPC, eq)));
    } else if (property.startsWith("EDR")) {
      ret.append(Delta.toString(EqToken.getEdrTokenInt(aPC, eq)));
    } else if (property.startsWith("ISTYPE")) {
      if (eq.isType(property.substring(property.indexOf(".") + 1))) {
        ret.append("TRUE");
      } else {
        ret.append("FALSE");
      }
    } else if (property.startsWith("SPELLFAIL")) {
      ret.append(EqToken.getSpellFailureTokenInt(aPC, eq));
    } else if (property.startsWith("MOVE")) {
      final StringTokenizer aTok = new StringTokenizer(eq.moveString(), ",", false);
      String tempString = "";

      if (("M".equals(display.getSize()) || "S".equals(display.getSize()))
          && (aTok.countTokens() > 0)) {
        tempString = aTok.nextToken();

        if ("S".equals(display.getSize()) && (aTok.countTokens() > 1)) {
          tempString = aTok.nextToken();
        }
      }

      ret.append(tempString);
    } else if (property.startsWith("SPROP")) {
      ret.append(eq.getSpecialProperties(aPC));
    } else if (property.startsWith("TYPE")) {
      String typeString = "";

      if (eq.isLight()) {
        typeString = "Light";
      } else if (eq.isMedium()) {
        typeString = "Medium";
      } else if (eq.isHeavy()) {
        typeString = "Heavy";
      } else if (eq.isShield()) {
        typeString = "Shield";
      } else if (eq.isExtra()) {
        typeString = "Extra";
      }

      ret.append(typeString);
    } else if (property.startsWith("WT")) {
      ret.append(BigDecimalHelper.trimZeros(eq.getWeight(aPC).toString()));
    }
    return ret.toString();
  }
Beispiel #23
0
  // TODO Refactor this with all the equipment tests.
  @Override
  public int passes(final Prerequisite prereq, final CharacterDisplay display, CDOMObject source)
      throws PrerequisiteException {
    final int number;
    try {
      number = Integer.parseInt(prereq.getOperand());
    } catch (NumberFormatException e) {
      throw new PrerequisiteException(
          LanguageBundle.getFormattedString(
              "PreItem.error.bad_operand", prereq.toString())); // $NON-NLS-1$
    }

    int runningTotal = 0;

    if (display.hasEquipment()) {
      // Work out exactlywhat we are going to test.
      final String aString = prereq.getKey();
      List<String> typeList = null;
      if (aString.startsWith(Constants.LST_TYPE_EQUAL)
          || aString.startsWith(Constants.LST_TYPE_DOT)) {
        String stripped = aString.substring(Constants.SUBSTRING_LENGTH_FIVE);
        typeList = CoreUtility.split(stripped, '.');
      }

      for (Equipment eq : display.getEquipmentSet()) {
        if (typeList != null) {
          // Check to see if the equipment matches
          // all of the types in the requested list;
          boolean bMatches = true;
          for (int i = 0, x = typeList.size(); i < x; ++i) {
            if (!eq.isType(typeList.get(i))) {
              bMatches = false;
              break;
            }
          }
          if (bMatches) {
            runningTotal++;
          }
        } else { // not a TYPE string
          final String eqName = eq.getName().toUpperCase();

          if (aString.indexOf('%') >= 0) {
            // handle wildcards (always assume
            // they end the line)
            final int percentPos = aString.indexOf('%');
            final String substring = aString.substring(0, percentPos).toUpperCase();
            if ((eqName.startsWith(substring))) {
              ++runningTotal;
              break;
            }
          } else if (eqName.equalsIgnoreCase(aString)) {
            // just a straight String compare
            ++runningTotal;
            break;
          }
        }
      }
    }

    runningTotal = prereq.getOperator().compare(runningTotal, number);
    return countedTotal(prereq, runningTotal);
  }
  /* (non-Javadoc)
   * @see pcgen.core.facade.SpellSupportFacade#getClassInfo(pcgen.core.facade.ClassFacade)
   */
  @Override
  public String getClassInfo(ClassFacade spellcaster) {
    if (!(spellcaster instanceof PCClass)) {
      return "";
    }
    PCClass aClass = (PCClass) spellcaster;
    SpellSupportForPCClass spellSupport = pc.getSpellSupport(aClass);
    int highestSpellLevel = spellSupport.getHighestLevelSpell(pc);

    final HtmlInfoBuilder b = new HtmlInfoBuilder();
    b.append("<table border=1><tr><td><font size=-2><b>"); // $NON-NLS-1$
    b.append(OutputNameFormatting.piString(aClass, false)).append(" ["); // $NON-NLS-1$
    b.append(
        String.valueOf(
            charDisplay.getLevel(aClass)
                + (int) pc.getTotalBonusTo("PCLEVEL", aClass.getKeyName()))); // $NON-NLS-1$
    b.append("]</b></font></td>"); // $NON-NLS-1$

    for (int i = 0; i <= highestSpellLevel; ++i) {
      b.append("<td><font size=-2><b><center>&nbsp;"); // $NON-NLS-1$
      b.append(String.valueOf(i));
      b.append("&nbsp;</b></center></font></td>"); // $NON-NLS-1$
    }

    b.append("</tr>"); // $NON-NLS-1$
    b.append("<tr><td><font size=-1><b>Cast</b></font></td>"); // $NON-NLS-1$

    for (int i = 0; i <= highestSpellLevel; ++i) {
      b.append("<td><font size=-1><center>"); // $NON-NLS-1$
      b.append(getNumCast(aClass, i, pc));
      b.append("</center></font></td>"); // $NON-NLS-1$
    }
    b.append("</tr>"); // $NON-NLS-1$

    // Making sure KnownList can be handled safely and produces the correct behaviour
    if (spellSupport.hasKnownList() || spellSupport.hasKnownSpells(pc)) {
      b.append("<tr><td><font size=-1><b>Known</b></font></td>"); // $NON-NLS-1$

      for (int i = 0; i <= highestSpellLevel; ++i) {
        final int a = spellSupport.getKnownForLevel(i, pc);
        final int bonus = spellSupport.getSpecialtyKnownForLevel(i, pc);

        b.append("<td><font size=-1><center>"); // $NON-NLS-1$
        b.append(String.valueOf(a));
        if (bonus > 0) {
          b.append('+').append(Integer.toString(bonus));
        }
        b.append("</center></font></td>"); // $NON-NLS-1$
      }
      b.append("</tr>"); // $NON-NLS-1$
    }

    b.append("<tr><td><font size=-1><b>DC</b></font></td>"); // $NON-NLS-1$

    for (int i = 0; i <= highestSpellLevel; ++i) {
      b.append("<td><font size=-1><center>"); // $NON-NLS-1$
      b.append(String.valueOf(getDC(aClass, i, pc)));
      b.append("</center></font></td>"); // $NON-NLS-1$
    }

    b.append("</tr></table>"); // $NON-NLS-1$

    b.appendI18nElement("InfoSpells.caster.type", aClass.getSpellType()); // $NON-NLS-1$
    b.appendLineBreak();
    b.appendI18nElement("InfoSpells.stat.bonus", aClass.getSpellBaseStat()); // $NON-NLS-1$

    if (pc.hasAssocs(aClass, AssociationKey.SPECIALTY) || charDisplay.hasDomains()) {
      boolean needComma = false;
      StringBuilder schoolInfo = new StringBuilder();
      String spec = pc.getAssoc(aClass, AssociationKey.SPECIALTY);
      if (spec != null) {
        schoolInfo.append(spec);
        needComma = true;
      }

      for (Domain d : charDisplay.getSortedDomainSet()) {
        if (needComma) {
          schoolInfo.append(',');
        }
        needComma = true;
        schoolInfo.append(d.getKeyName());
      }
      b.appendLineBreak();
      b.appendI18nElement("InfoSpells.school", schoolInfo.toString()); // $NON-NLS-1$
    }

    Set<String> set = new TreeSet<>();
    for (SpellProhibitor sp : aClass.getSafeListFor(ListKey.PROHIBITED_SPELLS)) {
      set.addAll(sp.getValueList());
    }

    Collection<? extends SpellProhibitor> prohibList = charDisplay.getProhibitedSchools(aClass);
    if (prohibList != null) {
      for (SpellProhibitor sp : prohibList) {
        set.addAll(sp.getValueList());
      }
    }
    if (!set.isEmpty()) {
      b.appendLineBreak();
      b.appendI18nElement(
          "InfoSpells.prohibited.school", //$NON-NLS-1$
          StringUtil.join(set, ",")); // $NON-NLS-1$
    }

    String bString = SourceFormat.getFormattedString(aClass, Globals.getSourceDisplay(), true);
    if (bString.length() > 0) {
      b.appendLineBreak();
      b.appendI18nElement("in_source", bString); // $NON-NLS-1$
    }

    return b.toString();
  }