/** Factory function to use for making DexStatValue. */
 public static StatValue newDexStatValue(
     final RaceValue raceValue,
     final ZithiaStat stat,
     final ArmorValue armorValue,
     final StatValue strValue) {
   if (stat != ZithiaStat.DEX) {
     throw new RuntimeException("Invalid: DexStatValue is only for dex.");
   }
   if (strValue.getStat() != ZithiaStat.STR) {
     throw new RuntimeException("Invalid: DexStatValue must be based on str.");
   }
   SettableIntValue value = new SettableIntValueImpl(stat.getDefaultValue());
   TweakableIntValue roll =
       new EquationIntValue(
           value,
           armorValue.getDefPenalty(),
           strValue.getValue(),
           new Equation3() {
             public int getValue(int dex, int defPenalty, int str) {
               int normalRoll = stat.getRoll(dex);
               return normalRoll - ArmorType.strAdjustedArmorPenalty(str, defPenalty);
             }
           });
   TweakableIntValue cost = new StatCost(stat, raceValue.getRace(), value);
   return new DexStatValue(stat, value, roll, cost);
 }
 public StatValue(final RaceValue raceValue, final ZithiaStat stat) {
   this.stat = stat;
   value = new SettableIntValueImpl(stat.getDefaultValue());
   roll =
       new EquationIntValue(
           value,
           new Equation1() {
             public int getValue(int value) {
               return stat.getRoll(value);
             }
           });
   cost = new StatCost(stat, raceValue.getRace(), value);
 }