Example #1
0
 public static PersistentTransitionChoice<?> processOldAdd(LoadContext context, String first)
     throws PersistenceLayerException {
   int openParenLoc = first.indexOf('(');
   if (openParenLoc == -1) {
     Logging.errorPrint("Expected to have a ( : " + first);
     return null;
   }
   int closeParenLoc = first.lastIndexOf(')');
   if (openParenLoc == -1) {
     Logging.errorPrint("Expected to have a ) : " + first);
     return null;
   }
   String key = first.substring(7, openParenLoc);
   String choices = first.substring(openParenLoc + 1, closeParenLoc);
   String count = "";
   if (closeParenLoc != first.length() - 1) {
     count = first.substring(closeParenLoc + 1) + '|';
   }
   PCClass applied = new PCClass();
   ParseResult pr = context.processSubToken(applied, "ADD", key, count + choices);
   pr.printMessages();
   if (!pr.passed()) {
     return null;
   }
   context.commit();
   PersistentTransitionChoice<?> ptc = applied.getListFor(ListKey.ADD).get(0);
   return ptc;
 }
  /**
   * Remove a domain from the character.
   *
   * @param pc The character
   * @param domain The domain.
   */
  public static void removeDomain(PlayerCharacter pc, Domain domain) {
    ClassSource source = pc.getDomainSource(domain);
    PCClass aClass = pc.getClassKeyed(source.getPcclass().getKeyName());

    if (aClass != null) {
      int maxLevel;

      for (maxLevel = 0; maxLevel < 10; maxLevel++) {
        if (pc.getSpellSupport(aClass).getCastForLevel(maxLevel, pc) == 0) {
          break;
        }
      }

      if (maxLevel > 0) {
        removeSpellsFromClassForLevels(pc, domain, aClass);
      }

      if ((maxLevel > 1) && (aClass.getSafe(IntegerKey.KNOWN_SPELLS_FROM_SPECIALTY) == 0)) {
        DomainSpellList domainSpellList = domain.get(ObjectKey.DOMAIN_SPELLLIST);
        final List<Spell> aList =
            pc.getAllSpellsInLists(Collections.singletonList(domainSpellList));

        for (Spell gcs : aList) {
          if (SpellLevel.getFirstLvlForKey(gcs, domainSpellList, pc) < maxLevel) {
            pc.removeDomainSpellCount(aClass);
            break;
          }
        }
      }
    }

    if (!pc.isImporting()) {
      BonusActivation.deactivateBonuses(domain, pc);
    }
  }
Example #3
0
 @Override
 protected void setUp() throws Exception {
   super.setUp();
   lscFacet = FacetLibrary.getFacet(ListSkillCostFacet.class);
   sk = context.ref.constructCDOMObject(Skill.class, "MySkill");
   dragon = context.ref.constructCDOMObject(PCClass.class, "Dragon");
   dragon.addToListFor(ListKey.TYPE, Type.MONSTER);
   dragon.put(ObjectKey.IS_MONSTER, Boolean.TRUE);
   TokenRegistration.register(CHOOSE_SKILL_TOKEN);
   ChooserFactory.setDelegate(new MockUIDelegate());
 }
  /**
   * Sets the locked flag on a PC
   *
   * @param pc
   */
  public static void applyDomain(PlayerCharacter pc, Domain d) {
    ClassSource source = pc.getDomainSource(d);
    PCClass aClass = pc.getClassKeyed(source.getPcclass().getKeyName());
    if (aClass != null) {
      int maxLevel;

      for (maxLevel = 0; maxLevel < 10; maxLevel++) {
        if (pc.getSpellSupport(aClass).getCastForLevel(maxLevel, pc) == 0) {
          break;
        }
      }

      if (maxLevel > 0) {
        addSpellsToClassForLevels(pc, d, aClass, 0, maxLevel - 1);
      }

      if ((maxLevel > 1) && (aClass.getSafe(IntegerKey.KNOWN_SPELLS_FROM_SPECIALTY) == 0)) {
        DomainSpellList domainSpellList = d.get(ObjectKey.DOMAIN_SPELLLIST);
        final List<Spell> aList =
            pc.getAllSpellsInLists(Collections.singletonList(domainSpellList));

        for (Spell gcs : aList) {
          if (SpellLevel.getFirstLvlForKey(gcs, domainSpellList, pc) < maxLevel) {
            pc.setDomainSpellCount(aClass, 1);
            break;
          }
        }
      }
    }

    Collection<CDOMReference<Spell>> mods = d.getSafeListMods(Spell.SPELLS);
    for (CDOMReference<Spell> ref : mods) {
      Collection<Spell> spells = ref.getContainedObjects();
      Collection<AssociatedPrereqObject> assoc = d.getListAssociations(Spell.SPELLS, ref);
      for (AssociatedPrereqObject apo : assoc) {
        if (!PrereqHandler.passesAll(apo.getPrerequisiteList(), pc, d)) {
          continue;
        }
        for (Spell s : spells) {
          String book = apo.getAssociation(AssociationKey.SPELLBOOK);
          List<CharacterSpell> aList = pc.getCharacterSpells(aClass, s, book, -1);

          if (aList.isEmpty()) {
            Formula times = apo.getAssociation(AssociationKey.TIMES_PER_UNIT);
            CharacterSpell cs = new CharacterSpell(d, s);
            int resolvedTimes = times.resolve(pc, d.getQualifiedKey()).intValue();
            cs.addInfo(1, resolvedTimes, book);
            pc.addCharacterSpell(aClass, cs);
          }
        }
      }
    }
  }
  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;
  }
  /**
   * Test to ensure that a character will fail a test if it does not have the correct number of
   * levels in the class.
   *
   * @throws Exception
   */
  public void testCharWithMultipleSpellClasses() throws Exception {
    LoadContext context = Globals.getContext();
    final PCClass pcClass = new PCClass();
    pcClass.setName("MyClass");
    context.unconditionallyProcess(pcClass, "SPELLSTAT", "CHA");
    pcClass.put(StringKey.SPELLTYPE, "ARCANE");
    context.unconditionallyProcess(pcClass.getOriginalClassLevel(1), "CAST", "5,4");

    final PCClass pcClass2 = new PCClass();
    pcClass2.setName("Other Class");
    context.unconditionallyProcess(pcClass2, "SPELLSTAT", "INT");
    pcClass2.put(StringKey.SPELLTYPE, "ARCANE");
    context.unconditionallyProcess(pcClass2.getOriginalClassLevel(1), "CAST", "5,4");

    final PlayerCharacter character = getCharacter();
    setPCStat(character, cha, 12);
    setPCStat(character, intel, 12);
    character.incrementClassLevel(1, pcClass);
    character.incrementClassLevel(2, pcClass2);

    final PreClassParser producer = new PreClassParser();

    final Prerequisite prereq =
        producer.parse("CLASS", "1,SPELLCASTER.Arcane,SPELLCASTER.Arcane=2", false, false);

    final PreMult test = new PreMult();
    final int passes = test.passes(prereq, character, null);
    assertEquals(1, passes);
  }
Example #7
0
  public int getLevelApplied(PCClass cl) {
    int result = -1;

    Map<CDOMSingleRef<? extends PCClass>, Integer> ac = getMapFor(MapKey.APPLIED_CLASS);
    if (ac != null) {
      for (Map.Entry<CDOMSingleRef<? extends PCClass>, Integer> me : ac.entrySet()) {
        PCClass pcclass = me.getKey().get();
        if (pcclass.getKeyName().equalsIgnoreCase(cl.getKeyName())) {
          result = me.getValue();
        }
      }
    }

    return result;
  }
Example #8
0
  /*
   * @see TestCase#setUp()
   */
  @Override
  protected void setUp() throws Exception {
    super.setUp();
    LoadContext context = Globals.getContext();

    SettingsHandler.getGame().setSpellBaseDC("10+SPELLLEVEL+BASESPELLSTAT");

    SimpleLoader<BonusSpellInfo> bonusSpellLoader =
        new SimpleLoader<BonusSpellInfo>(BonusSpellInfo.class);
    try {
      URI testURI = new URI("file:/" + getClass().getName() + ".java");
      bonusSpellLoader.parseLine(context, "1	BASESTATSCORE:12	STATRANGE:8", testURI);
      bonusSpellLoader.parseLine(context, "2	BASESTATSCORE:14	STATRANGE:8", testURI);
      bonusSpellLoader.parseLine(context, "3	BASESTATSCORE:16	STATRANGE:8", testURI);
    } catch (URISyntaxException e) {
      throw new UnreachableError(e);
    }

    // Human
    human = new Race();

    final BonusObj bon = Bonus.newBonus(context, "FEAT|POOL|2");
    human.addToListFor(ListKey.BONUS, bon);

    arcaneClass = new PCClass();
    arcaneClass.setName("TestArcane");
    arcaneClass.put(StringKey.SPELLTYPE, "ARCANE");
    context.unconditionallyProcess(arcaneClass, "SPELLSTAT", "CHA");
    arcaneClass.put(ObjectKey.SPELLBOOK, false);
    arcaneClass.put(ObjectKey.MEMORIZE_SPELLS, false);
    context.unconditionallyProcess(arcaneClass.getOriginalClassLevel(1), "KNOWN", "4,2,1");
    context.unconditionallyProcess(arcaneClass.getOriginalClassLevel(1), "CAST", "3,1,0");
    context.getReferenceContext().importObject(arcaneClass);

    divineClass = new PCClass();
    divineClass.setName("TestDivine");
    divineClass.put(StringKey.SPELLTYPE, "DIVINE");
    context.unconditionallyProcess(divineClass, "SPELLSTAT", "WIS");
    divineClass.put(ObjectKey.SPELLBOOK, false);
    divineClass.put(ObjectKey.MEMORIZE_SPELLS, true);
    context.unconditionallyProcess(divineClass.getOriginalClassLevel(1), "CAST", "3,1,0");
    context.unconditionallyProcess(
        divineClass, "SPELLLEVEL", "CLASS|SPELLCASTER.Divine=1|Cure Light Wounds");
    context.getReferenceContext().importObject(divineClass);
    context.resolveDeferredTokens();
    context.getReferenceContext().buildDerivedObjects();
    context.getReferenceContext().resolveReferences(null);
  }
  public static void addDomainsUpToLevel(PCClass cl, final int aLevel, final PlayerCharacter aPC) {

    // any domains set by level would have already been saved
    // and don't need to be re-set at level up time
    if (aPC.isImporting()) {
      return;
    }

    /*
     * Note this uses ALL of the domains up to and including this level,
     * because there is the possibility (albeit strange) that the PC was not
     * qualified at a previous level change, but the PlayerCharacter is now
     * qualified for the given Domain. Even this has quirks, since it is
     * only applied at the time of level increase, but I think that quirk
     * should be resolved by a CDOM system around 6.0 - thpr 10/23/06
     */
    for (QualifiedObject<CDOMSingleRef<Domain>> qo : cl.getSafeListFor(ListKey.DOMAIN)) {
      CDOMSingleRef<Domain> ref = qo.getObject(aPC, cl);
      if (ref != null) {
        addDomain(aPC, cl, ref.resolvesTo());
      }
    }
    for (int i = 0; i <= aLevel; i++) {
      // TODO This stinks for really high level characters - can this ever
      // get null back?
      PCClassLevel pcl = aPC.getActiveClassLevel(cl, i);
      for (QualifiedObject<CDOMSingleRef<Domain>> qo : pcl.getSafeListFor(ListKey.DOMAIN)) {
        CDOMSingleRef<Domain> ref = qo.getObject(aPC, cl);
        if (ref != null) {
          addDomain(aPC, cl, ref.resolvesTo());
        }
      }
    }
  }
Example #10
0
  public static void removeDomainsForLevel(
      PCClass cl, final int removedLevel, final PlayerCharacter aPC) {

    /*
     * Note this uses ALL of the domains up to and including this level,
     * because there is the possibility (albeit strange) that the PC was
     * qualified at a previous level change, but the PlayerCharacter is now
     * not qualified for the given Domain. Even this has quirks, since it is
     * only applied at the time of level increase, but I think that quirk
     * should be resolved by a CDOM system around 6.0 - thpr 10/23/06
     */
    for (QualifiedObject<CDOMSingleRef<Domain>> qo : cl.getSafeListFor(ListKey.DOMAIN)) {
      CDOMSingleRef<Domain> ref = qo.getObject(aPC, cl);
      if (ref == null) {
        ref = qo.getRawObject();
        aPC.removeDomain(ref.resolvesTo());
      }
    }
    for (int i = 0; i <= removedLevel; i++) {
      // TODO This stinks for really high level characters - can this ever
      // get null back?
      PCClassLevel pcl = aPC.getActiveClassLevel(cl, i);
      for (QualifiedObject<CDOMSingleRef<Domain>> qo : pcl.getSafeListFor(ListKey.DOMAIN)) {
        CDOMSingleRef<Domain> ref = qo.getObject(aPC, cl);
        if ((ref == null) || (i == removedLevel)) {
          ref = qo.getRawObject();
          aPC.removeDomain(ref.resolvesTo());
        }
      }
    }
  }
  private void initializeObjects() {
    s1 = new Skill();
    s1.setName("s1");
    primaryContext.getReferenceContext().importObject(s1);

    s2 = new Skill();
    s2.setName("s2");
    primaryContext.getReferenceContext().importObject(s2);
    primaryContext.unconditionallyProcess(s2, "TYPE", "Masterful");

    s3 = new Skill();
    s3.setName("s3");
    primaryContext.getReferenceContext().importObject(s3);
    primaryContext.unconditionallyProcess(s3, "TYPE", "Masterful");

    s4 = new Skill();
    s4.setName("s4");
    s4.put(ObjectKey.EXCLUSIVE, Boolean.TRUE);
    primaryContext.unconditionallyProcess(s4, "TYPE", "Masterful");
    primaryContext.getReferenceContext().importObject(s4);

    s5 = new Skill();
    s5.setName("s5");
    s5.put(ObjectKey.EXCLUSIVE, Boolean.TRUE);
    primaryContext.getReferenceContext().importObject(s5);

    cl1 = new PCClass();
    cl1.setName("MyClass");
    primaryContext.getReferenceContext().importObject(cl1);
  }
  /**
   * Create a map of the spell nodes for a class in the supplied list. This is intended to allow
   * quick checking of the presence of a spell in the list.
   *
   * @param spellNodeList The list of spell nodes
   * @param pcClass The class to filter the map by
   * @return A double map to the class' spells from the list.
   */
  private DoubleKeyMapToList<SpellFacade, String, SpellNode> buildExistingSpellMap(
      DefaultListFacade<SpellNode> spellNodeList, PCClass pcClass) {
    DoubleKeyMapToList<SpellFacade, String, SpellNode> spellMap = new DoubleKeyMapToList<>();

    for (SpellNode spellNode : spellNodeList) {
      if (pcClass.equals(spellNode.getSpellcastingClass())) {
        spellMap.addToListFor(spellNode.getSpell(), spellNode.getSpellLevel(), spellNode);
      }
    }

    return spellMap;
  }
Example #13
0
  @Override
  public PCClass clone() {
    PCClass aClass = null;

    try {
      aClass = (PCClass) super.clone();

      List<KnownSpellIdentifier> ksl = getListFor(ListKey.KNOWN_SPELLS);
      if (ksl != null) {
        aClass.removeListFor(ListKey.KNOWN_SPELLS);
        for (KnownSpellIdentifier ksi : ksl) {
          aClass.addToListFor(ListKey.KNOWN_SPELLS, ksi);
        }
      }
      Map<AttackType, Integer> acmap = getMapFor(MapKey.ATTACK_CYCLE);
      if (acmap != null && !acmap.isEmpty()) {
        aClass.removeMapFor(MapKey.ATTACK_CYCLE);
        for (Map.Entry<AttackType, Integer> me : acmap.entrySet()) {
          aClass.addToMapFor(MapKey.ATTACK_CYCLE, me.getKey(), me.getValue());
        }
      }

      aClass.levelMap = new TreeMap<>();
      for (Map.Entry<Integer, PCClassLevel> me : levelMap.entrySet()) {
        aClass.levelMap.put(me.getKey(), me.getValue().clone());
      }
    } catch (CloneNotSupportedException exc) {
      ShowMessageDelegate.showMessageDialog(
          exc.getMessage(), Constants.APPLICATION_NAME, MessageType.ERROR);
    }

    return aClass;
  }
Example #14
0
 @Override
 public ParseResult parseToken(LoadContext context, PCClassLevel obj, String value) {
   if (ONE.equals(obj.get(IntegerKey.LEVEL))) {
     PCClass parent = (PCClass) obj.get(ObjectKey.TOKEN_PARENT);
     if (parent instanceof SubClass || parent instanceof SubstitutionClass) {
       return new ParseResult.Fail(
           "Data used token: "
               + value
               + " which is a Class token, "
               + "but it was used in a class level for a "
               + parent.getClass().getSimpleName(),
           context);
     }
     return wrappedToken.parseToken(context, parent, value);
   }
   return new ParseResult.Fail(
       "Data used token: "
           + value
           + " which is a Class token, "
           + "but it was used in a class level line other than level 1",
       context);
 }
Example #15
0
  /**
   * Needs documentation.
   *
   * @param pc update skills for this PC
   * @param aSkill Skill to update
   * @param aRank Number of ranks to add
   * @param aCost Cost of added ranks
   * @param langList Languages to be selected for a language skill
   * @param pcClass skills apply to this class
   * @return <code>true</code> for success TODO What about throwing on failure?
   */
  private boolean updatePCSkills(
      final PlayerCharacter pc,
      final Skill aSkill,
      final int aRank,
      final double aCost,
      List<Language> langList,
      final PCClass pcClass) {
    pc.addSkill(aSkill);

    boolean oldImporting = pc.isImporting();
    pc.setImporting(true);
    final String aString = SkillRankControl.modRanks(aRank, pcClass, true, pc, aSkill);
    pc.setImporting(oldImporting);

    if (aString.length() > 0) {
      Logging.errorPrint("SKILL: " + aString);
      return false;
    }

    // Add any supplied languages
    ChoiceManagerList<Language> controller =
        ChooserUtilities.getConfiguredController(aSkill, pc, null, new ArrayList<String>());
    for (Language lang : langList) {
      if (!controller.conditionallyApply(pc, lang)) {
        Logging.errorPrint("Failed to apply Language into Skill: " + lang.getLSTformat());
      }
    }

    //
    // Fix up the skill pools to reflect what we just spent.
    //
    double ptsToSpend = aCost;
    if (ptsToSpend >= 0.0) {
      for (PCLevelInfo info : pc.getLevelInfo()) {
        if (info.getClassKeyName().equals(pcClass.getKeyName())) {
          // We are spending this class' points.
          int remaining = info.getSkillPointsRemaining();
          if (remaining == 0) {
            continue;
          }
          int left = remaining - (int) Math.min(remaining, ptsToSpend);
          info.setSkillPointsRemaining(left);
          ptsToSpend -= (remaining - left);
          if (ptsToSpend <= 0) {
            break;
          }
        }
      }
    }
    return true;
  }
  /**
   * @see pcgen.io.exporttoken.Token#getToken(java.lang.String, pcgen.core.PlayerCharacter,
   *     pcgen.io.ExportHandler)
   */
  @Override
  public String getToken(String tokenSource, PlayerCharacter pc, ExportHandler eh) {
    StringBuffer retValue = new StringBuffer();

    SpellListTokenParams params =
        new SpellListTokenParams(tokenSource, SpellListToken.SPELLTAG_MEMORIZE);

    final CDOMObject aObject = pc.getSpellClassAtIndex(params.getClassNum());

    if (aObject != null) {
      PCClass aClass = null;

      if (aObject instanceof PCClass) {
        aClass = (PCClass) aObject;
      }

      if (aClass != null) {
        retValue.append((boolean) aClass.getSafe(ObjectKey.MEMORIZE_SPELLS));
      }
    }

    return retValue.toString();
  }
  /* (non-Javadoc)
   * @see pcgen.core.facade.SpellSupportFacade#addSpellList(java.lang.String)
   */
  @Override
  public void addSpellList(String spellList) {
    if (StringUtils.isEmpty(spellList)) {
      return;
    }

    // Prevent spellbooks being given the same name as a class
    for (PCClass current :
        Globals.getContext().getReferenceContext().getConstructedCDOMObjects(PCClass.class)) {
      if ((spellList.equals(current.getKeyName()))) {
        JOptionPane.showMessageDialog(
            null,
            LanguageBundle.getString("in_spellbook_name_error"), // $NON-NLS-1$
            Constants.APPLICATION_NAME,
            JOptionPane.ERROR_MESSAGE);

        return;
      }
    }

    if (pc.addSpellBook(spellList)) {
      pc.setDirty(true);

      DummySpellNodeImpl spellListNode = new DummySpellNodeImpl(getRootNode(spellList));
      preparedSpellLists.add(spellListNode);
      addDummyNodeIfSpellListEmpty(spellList);
    } else {
      JOptionPane.showMessageDialog(
          null,
          LanguageBundle.getFormattedString(
              "InfoPreparedSpells.add.list.fail", spellList), // $NON-NLS-1$
          Constants.APPLICATION_NAME,
          JOptionPane.ERROR_MESSAGE);

      return;
    }
  }
Example #18
0
  public static String getRanksExplanation(PlayerCharacter pc, Skill sk) {
    StringBuilder sb = new StringBuilder(100);
    boolean needComma = false;
    for (PCClass pcc : pc.getSkillRankClasses(sk)) {
      if (needComma) {
        sb.append(", ");
      }
      sb.append(pcc == null ? "None" : pcc.getKeyName());
      sb.append(':');
      Double rank = pc.getSkillRankForClass(sk, pcc);
      sb.append(rank == null ? 0 : rank);
      needComma = true;
    }
    double bonus = SkillRankControl.getSkillRankBonusTo(pc, sk);
    if (bonus != 0d) {
      if (sb.length() > 0) {
        sb.append("; ");
      }

      sb.append("Skillrank bonus ");
      sb.append(NumberFormat.getNumberInstance().format(bonus));
    }
    return sb.toString();
  }
  /* (non-Javadoc)
   * @see junit.framework.TestCase#setUp()
   */
  @Override
  protected void setUp() throws Exception {
    super.setUp();
    final PlayerCharacter character = getCharacter();

    myClass = new PCClass();
    myClass.setName("My Class");

    knowledge = new Skill();
    Globals.getContext().unconditionallyProcess(knowledge, "CLASSES", "My Class");
    knowledge.setName("KNOWLEDGE (ARCANA)");
    TestHelper.addType(knowledge, "KNOWLEDGE.INT");
    character.addSkill(knowledge);
    SkillRankControl.modRanks(8.0, myClass, true, character, knowledge);
  }
Example #20
0
  /*
   * CONSIDER Why does this not inherit classSkillChoices?
   */
  public void inheritAttributesFrom(final PCClass otherClass) {
    Boolean hbss = otherClass.get(ObjectKey.HAS_BONUS_SPELL_STAT);
    if (hbss != null) {
      put(ObjectKey.HAS_BONUS_SPELL_STAT, hbss);
      CDOMSingleRef<PCStat> bss = otherClass.get(ObjectKey.BONUS_SPELL_STAT);
      if (bss != null) {
        put(ObjectKey.BONUS_SPELL_STAT, bss);
      }
    }

    Boolean usbs = otherClass.get(ObjectKey.USE_SPELL_SPELL_STAT);
    if (usbs != null) {
      put(ObjectKey.USE_SPELL_SPELL_STAT, usbs);
    }
    Boolean cwss = otherClass.get(ObjectKey.CASTER_WITHOUT_SPELL_STAT);
    if (cwss != null) {
      put(ObjectKey.CASTER_WITHOUT_SPELL_STAT, cwss);
    }
    CDOMSingleRef<PCStat> ss = otherClass.get(ObjectKey.SPELL_STAT);
    if (ss != null) {
      put(ObjectKey.SPELL_STAT, ss);
    }

    TransitionChoice<CDOMListObject<Spell>> slc = otherClass.get(ObjectKey.SPELLLIST_CHOICE);
    if (slc != null) {
      put(ObjectKey.SPELLLIST_CHOICE, slc);
    }

    List<QualifiedObject<CDOMReference<Equipment>>> e = otherClass.getListFor(ListKey.EQUIPMENT);
    if (e != null) {
      addAllToListFor(ListKey.EQUIPMENT, e);
    }

    List<WeaponProfProvider> wp = otherClass.getListFor(ListKey.WEAPONPROF);
    if (wp != null) {
      addAllToListFor(ListKey.WEAPONPROF, wp);
    }
    QualifiedObject<Boolean> otherWP = otherClass.get(ObjectKey.HAS_DEITY_WEAPONPROF);
    if (otherWP != null) {
      put(ObjectKey.HAS_DEITY_WEAPONPROF, otherWP);
    }

    List<ArmorProfProvider> ap = otherClass.getListFor(ListKey.AUTO_ARMORPROF);
    if (ap != null) {
      addAllToListFor(ListKey.AUTO_ARMORPROF, ap);
    }

    List<ShieldProfProvider> sp = otherClass.getListFor(ListKey.AUTO_SHIELDPROF);
    if (sp != null) {
      addAllToListFor(ListKey.AUTO_SHIELDPROF, sp);
    }

    List<BonusObj> bonusList = otherClass.getListFor(ListKey.BONUS);
    if (bonusList != null) {
      addAllToListFor(ListKey.BONUS, bonusList);
    }
    try {
      ownBonuses(this);
    } catch (CloneNotSupportedException ce) {
      // TODO Auto-generated catch block
      ce.printStackTrace();
    }

    for (VariableKey vk : otherClass.getVariableKeys()) {
      put(vk, otherClass.get(vk));
    }

    if (otherClass.containsListFor(ListKey.CSKILL)) {
      removeListFor(ListKey.CSKILL);
      addAllToListFor(ListKey.CSKILL, otherClass.getListFor(ListKey.CSKILL));
    }

    if (otherClass.containsListFor(ListKey.LOCALCCSKILL)) {
      removeListFor(ListKey.LOCALCCSKILL);
      addAllToListFor(ListKey.LOCALCCSKILL, otherClass.getListFor(ListKey.LOCALCCSKILL));
    }

    removeListFor(ListKey.KIT_CHOICE);
    addAllToListFor(ListKey.KIT_CHOICE, otherClass.getSafeListFor(ListKey.KIT_CHOICE));

    remove(ObjectKey.REGION_CHOICE);
    if (otherClass.containsKey(ObjectKey.REGION_CHOICE)) {
      put(ObjectKey.REGION_CHOICE, otherClass.get(ObjectKey.REGION_CHOICE));
    }

    removeListFor(ListKey.SAB);
    addAllToListFor(ListKey.SAB, otherClass.getSafeListFor(ListKey.SAB));

    /*
     * TODO Does this need to have things from the Class Level objects?
     * I don't think so based on deferred processing of levels...
     */

    addAllToListFor(ListKey.DAMAGE_REDUCTION, otherClass.getListFor(ListKey.DAMAGE_REDUCTION));

    for (CDOMReference<Vision> ref : otherClass.getSafeListMods(Vision.VISIONLIST)) {
      for (AssociatedPrereqObject apo : otherClass.getListAssociations(Vision.VISIONLIST, ref)) {
        putToList(Vision.VISIONLIST, ref, apo);
      }
    }

    /*
     * TODO This is a clone problem, but works for now - thpr 10/3/08
     */
    if (otherClass instanceof SubClass) {
      levelMap.clear();
      copyLevelsFrom(otherClass);
    }

    addAllToListFor(ListKey.NATURAL_WEAPON, otherClass.getListFor(ListKey.NATURAL_WEAPON));

    put(ObjectKey.LEVEL_HITDIE, otherClass.get(ObjectKey.LEVEL_HITDIE));
  }
  /* (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();
  }
Example #22
0
  public double getMultiClassXPMultiplier(CharID id) {
    HashSet<PCClass> unfavoredClasses = new HashSet<PCClass>();
    SortedSet<PCClass> favored = new TreeSet<PCClass>(CDOMObjectUtilities.CDOM_SORTER);
    favored.addAll(favoredClassFacet.getSet(id));
    SortedSet<PCClass> aList = favored;
    boolean hasAny = hasAnyFavoredClassFacet.contains(id, Boolean.TRUE);
    PCClass maxClass = null;
    PCClass secondClass = null;
    int maxClassLevel = 0;
    int secondClassLevel = 0;
    int xpPenalty = 0;
    double xpMultiplier = 1.0;

    for (PCClass pcClass : classFacet.getClassSet(id)) {
      if (!pcClass.hasXPPenalty()) {
        continue;
      }
      String subClassKey = subClassFacet.getSource(id, pcClass);
      PCClass evalClass = pcClass;
      if (subClassKey != null && !subClassKey.equals("None")) {
        evalClass = pcClass.getSubClassKeyed(subClassKey);
      }
      if (!aList.contains(evalClass)) {
        unfavoredClasses.add(pcClass);

        int pcClassLevel = classFacet.getLevel(id, pcClass);
        if (pcClassLevel > maxClassLevel) {
          if (hasAny) {
            secondClassLevel = maxClassLevel;
            secondClass = maxClass;
          }

          maxClassLevel = pcClassLevel;
          maxClass = pcClass;
        } else if ((pcClassLevel > secondClassLevel) && (hasAny)) {
          secondClassLevel = pcClassLevel;
          secondClass = pcClass;
        }
      }
    }

    if ((hasAny) && (secondClassLevel > 0)) {
      maxClassLevel = secondClassLevel;
      unfavoredClasses.remove(maxClass);
      maxClass = secondClass;
    }

    if (maxClassLevel > 0) {
      unfavoredClasses.remove(maxClass);

      for (PCClass aClass : unfavoredClasses) {
        if ((maxClassLevel - (classFacet.getLevel(id, aClass))) > 1) {
          ++xpPenalty;
        }
      }

      xpMultiplier = 1.0 - (xpPenalty * 0.2);

      if (xpMultiplier < 0) {
        xpMultiplier = 0;
      }
    }

    return xpMultiplier;
  }
Example #23
0
  private KitSkillAdd addRanks(
      PlayerCharacter pc,
      PCClass pcClass,
      Skill aSkill,
      double ranksLeftToAdd,
      boolean isFree,
      List<String> warnings) {
    if (!isFree && pcClass.getSkillPool(pc) == 0) {
      return null;
    }

    double curRank = 0.0;
    if (pc.hasSkill(aSkill)) {
      curRank = pc.getRank(aSkill).doubleValue();
    }
    double ranksToAdd = ranksLeftToAdd;
    if (!Globals.checkRule(RuleConstants.SKILLMAX) && (ranksToAdd > 0.0)) {
      ranksToAdd = Math.min(pc.getMaxRank(aSkill, pcClass).doubleValue(), curRank + ranksLeftToAdd);
      ranksToAdd -= curRank;
      if (!CoreUtility.doublesEqual(ranksToAdd, ranksLeftToAdd)) {
        warnings.add(
            "SKILL: Could not add "
                + (ranksLeftToAdd - ranksToAdd)
                + " to "
                + aSkill.getDisplayName()
                + ". Exceeds MAXRANK of "
                + pc.getMaxRank(aSkill, pcClass)
                + ".");
      }
    }
    int ptsToSpend = 0;
    int[] points = new int[pc.getLevelInfoSize()];
    if (!isFree) {
      double ranksAdded = 0.0;
      int skillCost = pc.getSkillCostForClass(aSkill, pcClass).getCost();
      ptsToSpend = (int) (ranksToAdd * skillCost);
      for (int i = 0; i < pc.getLevelInfoSize(); i++) {
        PCLevelInfo info = pc.getLevelInfo(i);
        if (info.getClassKeyName().equals(pcClass.getKeyName())) {
          // We are spending this class' points.
          points[i] = info.getSkillPointsRemaining();
        } else {
          points[i] = -1;
        }
      }
      for (int i = 0; i < points.length; i++) {
        int remaining = points[i];
        if (remaining <= 0) {
          continue;
        }
        int left = remaining - Math.min(remaining, ptsToSpend);
        points[i] = left;
        int spent = (remaining - left);
        ptsToSpend -= spent;
        ranksAdded += ((double) spent / (double) skillCost);
        if (ranksAdded == ranksToAdd || ptsToSpend <= 0) {
          break;
        }
      }

      ranksToAdd = ranksAdded;
      ptsToSpend = (int) (ranksToAdd * skillCost);
    }
    pc.addSkill(aSkill);

    String ret = SkillRankControl.modRanks(ranksToAdd, pcClass, false, pc, aSkill);
    if (ret.length() > 0) {
      if (isFree && ret.indexOf("You do not have enough skill points.") != -1) {
        SkillRankControl.modRanks(ranksToAdd, pcClass, true, pc, aSkill);
      } else {
        warnings.add(ret);
        return null;
      }
    }
    if (!isFree) {
      for (int i = 0; i < pc.getLevelInfoSize(); i++) {
        PCLevelInfo info = pc.getLevelInfo(i);
        if (points[i] >= 0) {
          info.setSkillPointsRemaining(points[i]);
        }
      }
    }
    List<Language> langList = new ArrayList<Language>();
    if (ChooseActivation.hasChooseToken(aSkill) && !selection.isEmpty()) {
      ChoiceManagerList<Language> controller =
          ChooserUtilities.getConfiguredController(aSkill, pc, null, new ArrayList<String>());
      int limit = (int) ranksToAdd;
      for (CDOMSingleRef<Language> ref : selection) {
        Language lang = ref.resolvesTo();
        if (controller.conditionallyApply(pc, lang)) {
          langList.add(lang);
          limit--;
        }
        if (limit <= 0) {
          break;
        }
      }
    }
    return new KitSkillAdd(aSkill, ranksToAdd, ptsToSpend, langList, pcClass);
  }
 private boolean isSpellCaster(PCClass pcc) {
   return pcc.getSafe(ObjectKey.USE_SPELL_SPELL_STAT)
       || pcc.getSafe(ObjectKey.CASTER_WITHOUT_SPELL_STAT)
       || (pcc.get(ObjectKey.SPELL_STAT) != null);
 }