Example #1
0
 @Override
 public String[] unparse(LoadContext context, PCClass obj) {
   Changes<BonusObj> changes = context.getObjectContext().getListChanges(obj, ListKey.BONUS);
   if (changes == null || changes.isEmpty()) {
     // Empty indicates no token present
     return null;
   }
   // CONSIDER need to deal with removed...
   Collection<BonusObj> added = changes.getAdded();
   String tokenName = getTokenName();
   Set<String> bonusSet = new TreeSet<String>();
   for (BonusObj bonus : added) {
     if (tokenName.equals(bonus.getTokenSource())) {
       StringBuilder sb = new StringBuilder();
       sb.append(bonus.getValue());
       List<Prerequisite> prereqList = new ArrayList<Prerequisite>(bonus.getPrerequisiteList());
       Prerequisite prereq = getPrerequisite("PRELEVELMAX:1");
       prereqList.remove(prereq);
       if (!prereqList.isEmpty()) {
         sb.append('|');
         sb.append(getPrerequisiteString(context, prereqList));
       }
       bonusSet.add(sb.toString());
     }
   }
   if (bonusSet.isEmpty()) {
     // This is okay - just no BONUSes from this token
     return null;
   }
   return bonusSet.toArray(new String[bonusSet.size()]);
 }
Example #2
0
 /**
  * Add a CLASS via a BONUS
  *
  * @return true if successful
  */
 public static boolean addBonusClass(Class bonusClass)
     throws InstantiationException, IllegalAccessException {
   if (BonusObj.class.isAssignableFrom(bonusClass)) {
     final BonusObj bonusObj = (BonusObj) bonusClass.newInstance();
     BONUS_TAG_MAP.put(bonusObj.getBonusHandled(), bonusClass);
     return true;
   }
   return false;
 }
Example #3
0
 private static boolean bonusForThisSkill(BonusObj bonus, String keyName) {
   for (Object target : bonus.getBonusInfoList()) {
     if (String.valueOf(target).equalsIgnoreCase(keyName)) {
       return true;
     }
   }
   return false;
 }
Example #4
0
 @Override
 protected ParseResult parseNonEmptyToken(LoadContext context, PCClass pcc, String value) {
   BonusObj bon = Bonus.newBonus(context, "MONSKILLPTS|NUMBER|" + value);
   if (bon == null) {
     return new ParseResult.Fail(
         getTokenName() + " was given invalid bonus value: " + value, context);
   }
   Prerequisite prereq = getPrerequisite("PRELEVELMAX:1");
   if (prereq == null) {
     return new ParseResult.Fail(
         "Internal Error: " + getTokenName() + " had invalid prerequisite", context);
   }
   bon.addPrerequisite(prereq);
   bon.setTokenSource(getTokenName());
   context.getObjectContext().addToList(pcc, ListKey.BONUS, bon);
   return ParseResult.SUCCESS;
 }
Example #5
0
  public static String getSituationModifierExplanation(
      Skill sk, String situation, PlayerCharacter aPC, boolean shortForm) {
    List<String> explanation = new ArrayList<>();
    String keyName = sk.getKeyName();
    String bonusKey = ("SITUATION." + keyName + "=" + situation).toUpperCase();
    for (BonusObj bonus : aPC.getActiveBonusList()) {
      // calculate bonus and add to activeBonusMap
      if (aPC.isApplied(bonus) && "SITUATION".equals(bonus.getBonusName())) {
        boolean include = bonusForThisSkill(bonus, keyName);
        if (!include) {
          for (BonusPair bp : aPC.getStringListFromBonus(bonus)) {
            String bpKey = bp.fullyQualifiedBonusType.toUpperCase();
            if (bpKey.equals(bonusKey)) {
              include = true;
              break;
            }
          }
        }

        if (include) {
          double iBonus = 0;
          for (BonusPair bp : aPC.getStringListFromBonus(bonus)) {
            String bpKey = bp.fullyQualifiedBonusType.toUpperCase();
            if (bpKey.startsWith(bonusKey)) {
              iBonus += bp.resolve(aPC).doubleValue();
            }
          }
          if (!CoreUtility.doublesEqual(iBonus, 0.0)) {
            explanation.add(Delta.toString((int) iBonus) + aPC.getBonusContext(bonus, shortForm));
          }
        }
      }
    }

    return StringUtil.join(explanation, " ");
  }
Example #6
0
  /**
   * Builds up a string describing what makes up the misc modifier for a skill for a character. This
   * can either be in long form '+2[skill TUMBLE gteq 5|TYPE=SYNERGY.STACK]' or in short form
   * '+2[TUMBLE]'. Any modifiers that cannot be determined will be displayed as a single entry of
   * 'OTHER'.
   *
   * @param aPC The character associated with this skill.
   * @param shortForm True if the abbreviated form should be used.
   * @return The explanation of the misc modifier's make-up.
   */
  public static String getModifierExplanation(Skill sk, PlayerCharacter aPC, boolean shortForm) {
    double bonusObjTotal = 0.0;
    List<String> explanation = new ArrayList<>();
    String keyName = sk.getKeyName();
    String bonusKey = ("SKILL." + keyName).toUpperCase();
    for (BonusObj bonus : aPC.getActiveBonusList()) {
      // calculate bonus and add to activeBonusMap
      if (aPC.isApplied(bonus) && "SKILL".equals(bonus.getBonusName())) {
        boolean include = bonusForThisSkill(bonus, keyName);
        if (!include) {
          for (BonusPair bp : aPC.getStringListFromBonus(bonus)) {
            String bpKey = bp.fullyQualifiedBonusType.toUpperCase();
            if (bpKey.equals(bonusKey)) {
              include = true;
              break;
            }
          }
        }

        if (include) {
          double iBonus = 0;
          for (BonusPair bp : aPC.getStringListFromBonus(bonus)) {
            String bpKey = bp.fullyQualifiedBonusType.toUpperCase();
            if (bpKey.startsWith(bonusKey)) {
              iBonus += bp.resolve(aPC).doubleValue();
            }
          }
          if (!CoreUtility.doublesEqual(iBonus, 0.0)) {
            explanation.add(Delta.toString((int) iBonus) + aPC.getBonusContext(bonus, shortForm));
            bonusObjTotal += iBonus;
          }
        }
      }
    }

    StringBuilder bonusDetails = new StringBuilder();
    bonusDetails.append(StringUtil.joinToStringBuilder(explanation, " "));

    // TODO: Need to add other bonuses which are not encoded as bonus
    // objects
    // - familiars, racial, feats - and add them to bonusObjTotal

    double bonus;
    CDOMSingleRef<PCStat> statref = sk.get(ObjectKey.KEY_STAT);
    if (statref != null) {
      PCStat stat = statref.get();
      bonus = aPC.getStatModFor(stat);
      bonus += aPC.getTotalBonusTo("SKILL", "STAT." + stat.getKeyName());
      SkillCostDisplay.appendBonusDesc(bonusDetails, bonus, "STAT");
    }

    // The catch-all for non-bonusObj modifiers.
    bonus = aPC.getTotalBonusTo("SKILL", keyName) - bonusObjTotal;
    SkillCostDisplay.appendBonusDesc(bonusDetails, bonus, "OTHER");

    // loop through all current skill types checking for boni
    for (Type singleType : sk.getTrueTypeList(false)) {
      bonus = aPC.getTotalBonusTo("SKILL", "TYPE." + singleType);
      SkillCostDisplay.appendBonusDesc(bonusDetails, bonus, "TYPE." + singleType);
    }

    // now check for any lists of skills, etc
    bonus = aPC.getTotalBonusTo("SKILL", "LIST");
    SkillCostDisplay.appendBonusDesc(bonusDetails, bonus, "LIST");

    // now check for ALL
    bonus = aPC.getTotalBonusTo("SKILL", "ALL");
    SkillCostDisplay.appendBonusDesc(bonusDetails, bonus, "ALL");

    // these next two if-blocks try to get BONUS:[C]CSKILL|TYPE=xxx|y to
    // function
    if (aPC.isClassSkill(sk)) {
      bonus = aPC.getTotalBonusTo("CSKILL", keyName);
      SkillCostDisplay.appendBonusDesc(bonusDetails, bonus, "CSKILL");

      // loop through all current skill types checking for boni
      for (Type singleType : sk.getTrueTypeList(false)) {
        bonus = aPC.getTotalBonusTo("CSKILL", "TYPE." + singleType);
        SkillCostDisplay.appendBonusDesc(bonusDetails, bonus, "CSKILL");
      }

      bonus = aPC.getTotalBonusTo("CSKILL", "LIST");
      SkillCostDisplay.appendBonusDesc(bonusDetails, bonus, "CSKILL");
    }

    if (!aPC.isClassSkill(sk) && !sk.getSafe(ObjectKey.EXCLUSIVE)) {
      bonus = aPC.getTotalBonusTo("CCSKILL", keyName);
      SkillCostDisplay.appendBonusDesc(bonusDetails, bonus, "CCSKILL");

      // loop through all current skill types checking for boni
      for (Type singleType : sk.getTrueTypeList(false)) {
        bonus = aPC.getTotalBonusTo("CCSKILL", "TYPE." + singleType);
        SkillCostDisplay.appendBonusDesc(bonusDetails, bonus, "CCSKILL");
      }

      bonus = aPC.getTotalBonusTo("CCSKILL", "LIST");
      SkillCostDisplay.appendBonusDesc(bonusDetails, bonus, "CCSKILL");
    }

    // Encumbrance
    int aCheckMod = sk.getSafe(ObjectKey.ARMOR_CHECK).calculateBonus(aPC);
    SkillCostDisplay.appendBonusDesc(bonusDetails, aCheckMod, "ARMOR");

    String aString = SettingsHandler.getGame().getRankModFormula();
    if (!aString.isEmpty()) {
      aString =
          aString.replaceAll(
              Pattern.quote("$$RANK$$"), SkillRankControl.getTotalRank(aPC, sk).toString());
      bonus = aPC.getVariableValue(aString, "").intValue();
      SkillCostDisplay.appendBonusDesc(bonusDetails, bonus, "RANKS");
    }

    return bonusDetails.toString();
  }
Example #7
0
 /**
  * Sets all the BonusObj's to "active"
  *
  * @param aPC
  */
 @Override
 public void activateBonuses(final PlayerCharacter aPC) {
   for (BonusObj bonus : getBonuses()) {
     aPC.setApplied(bonus, bonus.qualifies(aPC, null));
   }
 }
Example #8
0
  /*
   * REFACTOR There is potentially redundant information here - level and PC...
   * is this ever out of sync or can this method be removed/made private??
   */
  public double getBonusTo(
      final String argType, final String argMname, final int asLevel, final PlayerCharacter aPC) {
    double i = 0;

    List<BonusObj> rawBonusList = getRawBonusList(aPC);

    for (int lvl = 1; lvl < asLevel; lvl++) {
      rawBonusList.addAll(aPC.getActiveClassLevel(this, lvl).getRawBonusList(aPC));
    }
    if ((asLevel == 0) || rawBonusList.isEmpty()) {
      return 0;
    }

    final String type = argType.toUpperCase();
    final String mname = argMname.toUpperCase();

    for (final BonusObj bonus : rawBonusList) {
      final StringTokenizer breakOnPipes =
          new StringTokenizer(bonus.toString().toUpperCase(), Constants.PIPE, false);
      final String theType = breakOnPipes.nextToken();

      if (!theType.equals(type)) {
        continue;
      }

      final String str = breakOnPipes.nextToken();
      final StringTokenizer breakOnCommas = new StringTokenizer(str, Constants.COMMA, false);

      while (breakOnCommas.hasMoreTokens()) {
        final String theName = breakOnCommas.nextToken();

        if (theName.equals(mname)) {
          final String aString = breakOnPipes.nextToken();
          final List<Prerequisite> localPreReqList = new ArrayList<>();
          if (bonus.hasPrerequisites()) {
            localPreReqList.addAll(bonus.getPrerequisiteList());
          }

          // TODO: This code should be removed after the 5.8 release
          // as the prereqs are processed by the bonus loading code.
          while (breakOnPipes.hasMoreTokens()) {
            final String bString = breakOnPipes.nextToken();

            if (PreParserFactory.isPreReqString(bString)) {
              Logging.debugPrint(
                  "Why is this prerequisite '"
                      + bString
                      + "' parsed in '"
                      + getClass().getName()
                      + ".getBonusTo(String,String,int)' rather than in the persistence layer?"); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
              try {
                final PreParserFactory factory = PreParserFactory.getInstance();
                localPreReqList.add(factory.parse(bString));
              } catch (PersistenceLayerException ple) {
                Logging.errorPrint(ple.getMessage(), ple);
              }
            }
          }

          // must meet criteria for bonuses before adding them in
          // TODO: This is a hack to avoid VARs etc in class defs
          // being qualified for when Bypass class prereqs is
          // selected.
          // Should we be passing in the BonusObj here to allow it to
          // be referenced in Qualifies statements?
          if (PrereqHandler.passesAll(localPreReqList, aPC, null)) {
            final double j = aPC.getVariableValue(aString, getQualifiedKey()).doubleValue();
            i += j;
          }
        }
      }
    }

    return i;
  }