mirror of
https://gitlab.com/phoenix-dvpmt/mmoitems.git
synced 2025-01-21 09:21:21 +01:00
Added ranges to numerical stats randomization
This commit is contained in:
parent
56359e0b61
commit
4a38952310
@ -12,6 +12,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Random;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* That Gaussian spread distribution thing that no one understands.
|
||||
@ -19,21 +20,24 @@ import java.util.Random;
|
||||
* @author indyuce
|
||||
*/
|
||||
public class NumericStatFormula implements RandomStatData<DoubleData>, UpdatableRandomStatData<DoubleData> {
|
||||
private final double base, scale, spread, maxSpread;
|
||||
private final double base, scale, spread, maxSpread, min, max;
|
||||
private final boolean uniform, hasMin, hasMax;
|
||||
|
||||
private static final Random RANDOM = new Random();
|
||||
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0.####");
|
||||
|
||||
public static final NumericStatFormula ZERO = new NumericStatFormula(0, 0, 0, 0);
|
||||
|
||||
private final static double DEFAULT_MAX_SPREAD = .3;
|
||||
|
||||
/**
|
||||
* When reading a numeric stat formula either from a config file
|
||||
* (configuration section, or number) or when reading player input when a
|
||||
* player edits a stat (string message). Although the string format would
|
||||
* work in the config as well.
|
||||
*
|
||||
* <p>
|
||||
* Throws an IAE either if the format is not good or if the object does not
|
||||
* have the right type
|
||||
* have the right type.
|
||||
*
|
||||
* @param object Object to read data from.
|
||||
*/
|
||||
@ -41,41 +45,91 @@ public class NumericStatFormula implements RandomStatData<DoubleData>, Updatable
|
||||
Validate.notNull(object, "Config must not be null");
|
||||
|
||||
if (object instanceof String) {
|
||||
|
||||
// Uniform range from string
|
||||
if (object.toString().contains("->")) {
|
||||
String[] split = object.toString().replace(" ", "").split(Pattern.quote("->"));
|
||||
base = 0;
|
||||
scale = 0;
|
||||
spread = 0;
|
||||
maxSpread = 0;
|
||||
uniform = true;
|
||||
hasMin = true;
|
||||
hasMax = true;
|
||||
min = Double.parseDouble(split[0]);
|
||||
max = Double.parseDouble(split[1]);
|
||||
}
|
||||
|
||||
// Gaussian distribution from string
|
||||
else {
|
||||
String[] split = object.toString().split(" ");
|
||||
base = Double.parseDouble(split[0]);
|
||||
scale = split.length > 1 ? Double.parseDouble(split[1]) : 0;
|
||||
spread = split.length > 2 ? Double.parseDouble(split[2]) : 0;
|
||||
maxSpread = split.length > 3 ? Double.parseDouble(split[3]) : 0;
|
||||
return;
|
||||
hasMin = split.length > 4;
|
||||
hasMax = split.length > 5;
|
||||
min = hasMin ? Double.parseDouble(split[4]) : 0;
|
||||
max = hasMax ? Double.parseDouble(split[5]) : 0;
|
||||
uniform = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (object instanceof Number) {
|
||||
// Constant
|
||||
else if (object instanceof Number) {
|
||||
base = Double.parseDouble(object.toString());
|
||||
scale = 0;
|
||||
spread = 0;
|
||||
maxSpread = 0;
|
||||
return;
|
||||
uniform = false;
|
||||
hasMin = false;
|
||||
hasMax = false;
|
||||
min = 0;
|
||||
max = 0;
|
||||
}
|
||||
|
||||
if (object instanceof ConfigurationSection) {
|
||||
// Load from config section
|
||||
else if (object instanceof ConfigurationSection) {
|
||||
ConfigurationSection config = (ConfigurationSection) object;
|
||||
base = config.getDouble("base");
|
||||
scale = config.getDouble("scale");
|
||||
spread = config.getDouble("spread");
|
||||
maxSpread = config.getDouble("max-spread", .3);
|
||||
|
||||
Validate.isTrue(spread >= 0, "Spread must be positive");
|
||||
Validate.isTrue(maxSpread >= 0, "Max spread must be positive");
|
||||
return;
|
||||
maxSpread = config.getDouble("max-spread", DEFAULT_MAX_SPREAD);
|
||||
hasMin = config.contains("min");
|
||||
hasMax = config.contains("max");
|
||||
uniform = !config.contains("spread") && !config.contains("scale") && !config.contains("base") && hasMin && hasMax;
|
||||
min = config.getDouble("min");
|
||||
max = config.getDouble("max");
|
||||
}
|
||||
|
||||
// Error
|
||||
else {
|
||||
throw new IllegalArgumentException("Must specify a config section, a string or a number");
|
||||
}
|
||||
|
||||
// Validates
|
||||
Validate.isTrue(spread >= 0, "Spread must be positive");
|
||||
Validate.isTrue(maxSpread >= 0, "Max spread must be positive");
|
||||
}
|
||||
|
||||
/**
|
||||
* Formula for numeric statistics. These formulas allow stats to scale
|
||||
* A gaussian distribution with spread-based boundaries
|
||||
*/
|
||||
public NumericStatFormula(double base, double scale, double spread, double maxSpread) {
|
||||
this(base, scale, spread, maxSpread, false, false, 0, false, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* A gaussian distribution with constant boundaries
|
||||
*/
|
||||
public NumericStatFormula(double base, double scale, double spread, double min, double max) {
|
||||
this(base, scale, spread, 100, false, true, min, true, max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formula for numerical statistics. These formulas allow stats to scale
|
||||
* accordingly to the item level but also have a more or less important
|
||||
* gaussian based random factor
|
||||
* gaussian/uniform based random factor.
|
||||
*
|
||||
* @param base Base value
|
||||
* @param scale Value which scales with the item level
|
||||
@ -86,35 +140,52 @@ public class NumericStatFormula implements RandomStatData<DoubleData>, Updatable
|
||||
* @param maxSpread The max amount of deviation you can have. If it's set to
|
||||
* 0.3, let A = base + scale * level, then the final stat
|
||||
* value will be in [0.7 * A, 1.3 * A]
|
||||
* @param hasMin Should the value have a lower threshold
|
||||
* @param min Lower bound for numerical value
|
||||
* @param hasMax Should the value have an upper threshold
|
||||
* @param min Upper bound for numerical value
|
||||
*/
|
||||
public NumericStatFormula(double base, double scale, double spread, double maxSpread) {
|
||||
public NumericStatFormula(double base, double scale, double spread, double maxSpread,
|
||||
boolean uniform, boolean hasMin, double min, boolean hasMax, double max) {
|
||||
this.base = base;
|
||||
this.scale = scale;
|
||||
this.spread = spread;
|
||||
this.maxSpread = maxSpread;
|
||||
this.uniform = uniform;
|
||||
this.hasMin = hasMin;
|
||||
this.hasMax = hasMax;
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The 'Base' number of the item. This chooses the peak of the Gaussian Distribution.
|
||||
* @see #getScale()
|
||||
*/
|
||||
public double getBase() { return base; }
|
||||
|
||||
public double getBase() {
|
||||
return base;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return When the item has a certain level or tier, this is how much each level shifts
|
||||
* the peak, so that it is centered at {@code base + scale*level}
|
||||
* @see #getBase()
|
||||
*/
|
||||
public double getScale() { return scale; }
|
||||
public double getScale() {
|
||||
return scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Standard Deviation of the Gaussian Distribution
|
||||
*/
|
||||
public double getSpread() { return spread; }
|
||||
public double getSpread() {
|
||||
return spread;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return For gaussian distributions, there always is that INSANELY SMALL chance of getting an INSANELY LARGE number.
|
||||
* @return For gaussian distributions, there always is that INSANELY SMALL
|
||||
* chance of getting an INSANELY LARGE number.
|
||||
* <p>
|
||||
* For example: At base atk dmg 10, and standard deviation 1:
|
||||
* <p>68% of rolls will fall between 9 and 11;
|
||||
* </p>95% of rolls will fall between 8 and 12;
|
||||
@ -123,9 +194,31 @@ public class NumericStatFormula implements RandomStatData<DoubleData>, Updatable
|
||||
* <p></p>
|
||||
* Whatever, this constrains to a minimum and maximum of output.
|
||||
*/
|
||||
public double getMaxSpread() { return maxSpread; }
|
||||
public double getMaxSpread() {
|
||||
return maxSpread;
|
||||
}
|
||||
|
||||
public static boolean useRelativeSpread;
|
||||
public boolean isUniform() {
|
||||
return uniform;
|
||||
}
|
||||
|
||||
public boolean hasMin() {
|
||||
return hasMin;
|
||||
}
|
||||
|
||||
public boolean hasMax() {
|
||||
return hasMax;
|
||||
}
|
||||
|
||||
public double getMin() {
|
||||
return min;
|
||||
}
|
||||
|
||||
public double getMax() {
|
||||
return max;
|
||||
}
|
||||
|
||||
public static boolean RELATIVE_SPREAD;
|
||||
|
||||
/**
|
||||
* Applies the formula for a given input x.
|
||||
@ -133,7 +226,6 @@ public class NumericStatFormula implements RandomStatData<DoubleData>, Updatable
|
||||
* @param levelScalingFactor When choosing the mean of the distribution,
|
||||
* the formula is <code>base + (scale*level)</code>.
|
||||
* This is the <code>level</code>
|
||||
*
|
||||
* @return <b>Legacy formula: ???</b><br>
|
||||
* Let A = {base} + {scale} * lvl, then the returned value is a
|
||||
* random value taken in respect to a gaussian distribution
|
||||
@ -148,19 +240,25 @@ public class NumericStatFormula implements RandomStatData<DoubleData>, Updatable
|
||||
public double calculate(double levelScalingFactor) {
|
||||
|
||||
// Calculate yes
|
||||
return calculate(levelScalingFactor, RANDOM.nextGaussian());
|
||||
return calculate(levelScalingFactor, uniform ? RANDOM.nextDouble() : RANDOM.nextGaussian());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param levelScalingFactor Level to scale the scale with
|
||||
* @param scaleFactor Level to scale the scale with
|
||||
* @param random Result of <code>RANDOM.nextGaussian()</code> or whatever other
|
||||
* value that you actually want to pass.
|
||||
* @return The calculated value
|
||||
* value that you actually want to pass. It can be any valuation of
|
||||
* a random variable with mean 0 and variance 1.
|
||||
* @return The calculated final numerical value
|
||||
*/
|
||||
public double calculate(double levelScalingFactor, double random) {
|
||||
public double calculate(double scaleFactor, double random) {
|
||||
|
||||
double value;
|
||||
if (uniform) {
|
||||
value = min + (max - min) * random;
|
||||
} else {
|
||||
|
||||
// The mean, the center of the distribution
|
||||
final double actualBase = base + (scale * levelScalingFactor);
|
||||
final double actualBase = base + (scale * scaleFactor);
|
||||
|
||||
/*
|
||||
* This is one pick from a gaussian distribution at mean 0, and
|
||||
@ -169,7 +267,12 @@ public class NumericStatFormula implements RandomStatData<DoubleData>, Updatable
|
||||
*/
|
||||
final double spreadCoef = Math.min(Math.max(random * spread, -maxSpread), maxSpread);
|
||||
|
||||
return useRelativeSpread ? actualBase * (1 + spreadCoef) : actualBase + spreadCoef;
|
||||
value = RELATIVE_SPREAD ? actualBase * (1 + spreadCoef) : actualBase + spreadCoef;
|
||||
if (hasMin) value = Math.max(min, value);
|
||||
if (hasMax) value = Math.max(max, value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -179,24 +282,33 @@ public class NumericStatFormula implements RandomStatData<DoubleData>, Updatable
|
||||
|
||||
/**
|
||||
* Save some formula in a config file. This method is used when editing stat
|
||||
* data in the edition GUI (when a player inputs a numeric formula)
|
||||
* data in the edition GUI (when a player inputs a numeric formula).
|
||||
*
|
||||
* @param config The formula will be saved in that config file
|
||||
* @param path The config path used to save the formula
|
||||
* @param option If zero formulas should be ignored
|
||||
*/
|
||||
public void fillConfigurationSection(ConfigurationSection config, String path, FormulaSaveOption option) {
|
||||
public void fillConfigurationSection(@NotNull ConfigurationSection config, @NotNull String path, @NotNull FormulaSaveOption option) {
|
||||
if (path == null)
|
||||
throw new NullPointerException("Path was empty");
|
||||
throw new NullPointerException("Path is empty");
|
||||
|
||||
if (scale == 0 && spread == 0 && maxSpread == 0)
|
||||
if (scale == 0 && spread == 0 && maxSpread == 0 && !uniform) {
|
||||
config.set(path, base == 0 && option == FormulaSaveOption.DELETE_IF_ZERO ? null : base);
|
||||
|
||||
else {
|
||||
config.set(path + ".base", base);
|
||||
config.set(path + ".scale", scale);
|
||||
config.set(path + ".spread", spread);
|
||||
config.set(path + ".max-spread", maxSpread);
|
||||
return;
|
||||
}
|
||||
|
||||
config.createSection(path);
|
||||
config = config.getConfigurationSection(path);
|
||||
|
||||
if (!uniform) {
|
||||
config.set("base", base);
|
||||
config.set("scale", scale);
|
||||
config.set("spread", spread);
|
||||
config.set("max-spread", maxSpread);
|
||||
}
|
||||
|
||||
if (hasMin) config.set("min", min);
|
||||
if (hasMax) config.set("max", max);
|
||||
}
|
||||
|
||||
public void fillConfigurationSection(ConfigurationSection config, String path) {
|
||||
@ -217,7 +329,9 @@ public class NumericStatFormula implements RandomStatData<DoubleData>, Updatable
|
||||
+ (maxSpread != 0 ? ",Max=" + maxSpread : "") + "}";
|
||||
}
|
||||
|
||||
public static void reload() { useRelativeSpread = !MMOItems.plugin.getConfig().getBoolean("additive-spread-formula", false); }
|
||||
public static void reload() {
|
||||
RELATIVE_SPREAD = !MMOItems.plugin.getConfig().getBoolean("additive-spread-formula", false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -228,7 +342,7 @@ public class NumericStatFormula implements RandomStatData<DoubleData>, Updatable
|
||||
final double expectedValue = getBase() + (getScale() * determinedItemLevel);
|
||||
final double previousValue = original.getValue();
|
||||
final double shift = previousValue - expectedValue;
|
||||
final double shiftSD = useRelativeSpread ? Math.abs(shift / (getSpread() * expectedValue)) : Math.abs(shift / getSpread());
|
||||
final double shiftSD = RELATIVE_SPREAD ? Math.abs(shift / (getSpread() * expectedValue)) : Math.abs(shift / getSpread());
|
||||
final double maxSD = getMaxSpread() / getSpread();
|
||||
|
||||
// Greater than max spread? Or heck, 0.1% Chance or less wth
|
||||
@ -242,7 +356,8 @@ public class NumericStatFormula implements RandomStatData<DoubleData>, Updatable
|
||||
//UPGRD//MMOItems.log("\u00a7a +\u00a77 Acceptable Range --- kept");
|
||||
|
||||
// Just clone I guess
|
||||
return original.cloneData(); }
|
||||
return original.cloneData();
|
||||
}
|
||||
}
|
||||
|
||||
public enum FormulaSaveOption {
|
||||
|
@ -75,7 +75,9 @@ public class DoubleStat extends ItemStat<NumericStatFormula, DoubleData> impleme
|
||||
* Usually, a greater magnitude of stat benefits the player (more health, more attack damage).
|
||||
* <p>However, its not impossible for a stat to be evil instead, who knows?
|
||||
*/
|
||||
public boolean moreIsBetter() { return moreIsBetter; }
|
||||
public boolean moreIsBetter() {
|
||||
return moreIsBetter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NumericStatFormula whenInitialized(Object object) {
|
||||
@ -96,7 +98,9 @@ public class DoubleStat extends ItemStat<NumericStatFormula, DoubleData> impleme
|
||||
double value = data.getValue();
|
||||
|
||||
// Cancel if it its NEGATIVE and this doesn't support negative stats.
|
||||
if (value < 0 && !handleNegativeStats()) { return; }
|
||||
if (value < 0 && !handleNegativeStats()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Identify the upgrade amount
|
||||
double upgradeShift = 0;
|
||||
@ -113,11 +117,13 @@ public class DoubleStat extends ItemStat<NumericStatFormula, DoubleData> impleme
|
||||
DoubleData uData = (DoubleData) hist.recalculateUnupgraded();
|
||||
|
||||
// Calculate Difference
|
||||
upgradeShift = value - uData.getValue(); } }
|
||||
upgradeShift = value - uData.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
// Display in lore
|
||||
if (value != 0 || upgradeShift != 0) {
|
||||
String loreInsert = formatPath(getId(), MMOItems.plugin.getLanguage().getStatFormat(getPath()), moreIsBetter, value * multiplyWhenDisplaying());
|
||||
String loreInsert = formatPath(getId(), getGeneralStatFormat(), moreIsBetter, value * multiplyWhenDisplaying());
|
||||
if (upgradeShift != 0)
|
||||
loreInsert += UpgradeTemplate.getUpgradeChangeSuffix(plus(upgradeShift * multiplyWhenDisplaying()) + (MythicLib.plugin.getMMOConfig().decimals.format(upgradeShift * multiplyWhenDisplaying())), !isGood(upgradeShift * multiplyWhenDisplaying()));
|
||||
item.getLore().insert(getPath(), loreInsert);
|
||||
@ -129,7 +135,9 @@ public class DoubleStat extends ItemStat<NumericStatFormula, DoubleData> impleme
|
||||
* It is important that the tags are not excluded in getAppliedNBT() because the StatHistory does
|
||||
* need that blanc tag information to remember when an Item did not initially have any of a stat.
|
||||
*/
|
||||
if (data.getValue() != 0) { item.addItemTag(getAppliedNBT(data)); }
|
||||
if (data.getValue() != 0) {
|
||||
item.addItemTag(getAppliedNBT(data));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ -177,8 +185,12 @@ public class DoubleStat extends ItemStat<NumericStatFormula, DoubleData> impleme
|
||||
double techMaximum = templateData.calculate(0, 2.5);
|
||||
|
||||
// Cancel if it its NEGATIVE and this doesn't support negative stats.
|
||||
if (techMaximum < 0 && !handleNegativeStats()) { return; }
|
||||
if (techMinimum < 0 && !handleNegativeStats()) { techMinimum = 0; }
|
||||
if (techMaximum < 0 && !handleNegativeStats()) {
|
||||
return;
|
||||
}
|
||||
if (techMinimum < 0 && !handleNegativeStats()) {
|
||||
techMinimum = 0;
|
||||
}
|
||||
// Add NBT Path
|
||||
item.addItemTag(getAppliedNBT(currentData));
|
||||
|
||||
@ -187,22 +199,30 @@ public class DoubleStat extends ItemStat<NumericStatFormula, DoubleData> impleme
|
||||
|
||||
String builtRange;
|
||||
if (SilentNumbers.round(techMinimum, 2) == SilentNumbers.round(techMaximum, 2)) {
|
||||
builtRange = formatPath(getId(), MMOItems.plugin.getLanguage().getStatFormat(getPath()), moreIsBetter(), techMaximum * multiplyWhenDisplaying());
|
||||
builtRange = formatPath(getId(), getGeneralStatFormat(), moreIsBetter(), techMaximum * multiplyWhenDisplaying());
|
||||
|
||||
} else {
|
||||
builtRange = formatPath(getId(), MMOItems.plugin.getLanguage().getStatFormat(getPath()), moreIsBetter(), techMinimum * multiplyWhenDisplaying(), techMaximum * multiplyWhenDisplaying()); }
|
||||
|
||||
// Just display normally
|
||||
item.getLore().insert(getPath(), builtRange); }
|
||||
builtRange = formatPath(getId(), getGeneralStatFormat(), moreIsBetter(), techMinimum * multiplyWhenDisplaying(), techMaximum * multiplyWhenDisplaying());
|
||||
}
|
||||
|
||||
@NotNull public static String getColorPrefix(boolean isNegative) {
|
||||
// Just display normally
|
||||
item.getLore().insert(getPath(), builtRange);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getColorPrefix(boolean isNegative) {
|
||||
|
||||
// Get the base
|
||||
return Objects.requireNonNull(MMOItems.plugin.getConfig().getString("stats-displaying.color-" + (isNegative ? "negative" : "positive"), ""));
|
||||
}
|
||||
|
||||
@NotNull String plus(double amount) { if (amount >= 0) { return "+"; } else return ""; }
|
||||
@NotNull
|
||||
String plus(double amount) {
|
||||
if (amount >= 0) {
|
||||
return "+";
|
||||
} else return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Usually, a greater magnitude of stat benefits the player (more health, more attack damage).
|
||||
@ -241,7 +261,7 @@ public class DoubleStat extends ItemStat<NumericStatFormula, DoubleData> impleme
|
||||
relevantTags.add(ItemTag.getTagAtPath(getNBTPath(), mmoitem.getNBT(), SupportedNBTTagValues.DOUBLE));
|
||||
|
||||
// Use that
|
||||
DoubleData bakedData = (DoubleData) getLoadedNBT(relevantTags);
|
||||
DoubleData bakedData = getLoadedNBT(relevantTags);
|
||||
|
||||
// Valid?
|
||||
if (bakedData != null) {
|
||||
@ -250,6 +270,7 @@ public class DoubleStat extends ItemStat<NumericStatFormula, DoubleData> impleme
|
||||
mmoitem.setData(this, bakedData);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public DoubleData getLoadedNBT(@NotNull ArrayList<ItemTag> storedTags) {
|
||||
@ -282,62 +303,31 @@ public class DoubleStat extends ItemStat<NumericStatFormula, DoubleData> impleme
|
||||
|
||||
@Override
|
||||
public void whenInput(@NotNull EditionInventory inv, @NotNull String message, Object... info) {
|
||||
double base, scale, spread, maxSpread;
|
||||
|
||||
/*
|
||||
* Supports the old RANGE formula with a minimum and a maximum value and
|
||||
* automatically makes the conversion to the newest system. This way
|
||||
* users can keep using the old system if they don't want to adapt to
|
||||
* the complex gaussian stat calculation
|
||||
*/
|
||||
if (message.contains("->")) {
|
||||
String[] split = message.replace(" ", "").split(Pattern.quote("->"));
|
||||
Validate.isTrue(split.length > 1, "You must specify two (both min and max) values");
|
||||
|
||||
double min = Double.parseDouble(split[0]), max = Double.parseDouble(split[1]);
|
||||
Validate.isTrue(max > min, "Max value must be greater than min value");
|
||||
|
||||
base = MMOUtils.truncation(min == -max ? (max - min) * .05 : (min + max) / 2, 3);
|
||||
scale = 0; // No scale
|
||||
maxSpread = MMOUtils.truncation((max - min) / (2 * base), 3);
|
||||
spread = MMOUtils.truncation(.8 * maxSpread, 3);
|
||||
}
|
||||
|
||||
// Newest system with gaussian values calculation
|
||||
else {
|
||||
String[] split = message.split(" ");
|
||||
base = MMOUtils.parseDouble(split[0]);
|
||||
scale = split.length > 1 ? MMOUtils.parseDouble(split[1]) : 0;
|
||||
spread = split.length > 2 ? MMOUtils.parseDouble(split[2]) : 0;
|
||||
maxSpread = split.length > 3 ? MMOUtils.parseDouble(split[3]) : 0;
|
||||
}
|
||||
|
||||
// Save as a flat formula
|
||||
if (scale == 0 && spread == 0 && maxSpread == 0)
|
||||
inv.getEditedSection().set(getPath(), base);
|
||||
|
||||
else {
|
||||
inv.getEditedSection().set(getPath() + ".base", base);
|
||||
inv.getEditedSection().set(getPath() + ".scale", scale == 0 ? null : scale);
|
||||
inv.getEditedSection().set(getPath() + ".spread", spread == 0 ? null : spread);
|
||||
inv.getEditedSection().set(getPath() + ".max-spread", maxSpread == 0 ? null : maxSpread);
|
||||
}
|
||||
|
||||
final NumericStatFormula formula = new NumericStatFormula(message);
|
||||
formula.fillConfigurationSection(inv.getEditedSection(), getPath(), NumericStatFormula.FormulaSaveOption.DELETE_IF_ZERO);
|
||||
inv.registerTemplateEdition();
|
||||
inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + getName() + " successfully changed to {" + base + " - " + scale + " - " + spread
|
||||
+ " - " + maxSpread + "}");
|
||||
inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + getName() + " successfully changed to {"
|
||||
+ formula.getBase() + " - " + formula.getScale() + " - " + formula.getSpread() + " - " + formula.getMaxSpread() + " - ("
|
||||
+ formula.getMin() + " -> " + formula.getMax() + ") }");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void whenDisplayed(List<String> lore, Optional<NumericStatFormula> statData) {
|
||||
if (statData.isPresent()) {
|
||||
NumericStatFormula data = statData.get();
|
||||
if (data.isUniform()) {
|
||||
lore.add(ChatColor.GRAY + "Uniform: " + ChatColor.GREEN + DECIMAL_FORMAT.format(data.getMin()) + ChatColor.GRAY + " -> " + ChatColor.GREEN + DECIMAL_FORMAT.format(data.getMax()));
|
||||
} else {
|
||||
lore.add(ChatColor.GRAY + "Base Value: " + ChatColor.GREEN + DECIMAL_FORMAT.format(data.getBase())
|
||||
+ (data.getScale() != 0 ? ChatColor.GRAY + " (+" + ChatColor.GREEN + DECIMAL_FORMAT.format(data.getScale()) + ChatColor.GRAY + ")" : ""));
|
||||
+ (data.getScale() != 0 ? ChatColor.GRAY + " (+" + ChatColor.GREEN + DECIMAL_FORMAT.format(data.getScale()) + ChatColor.GRAY + "/Lvl)" : ""));
|
||||
if (data.getSpread() > 0)
|
||||
lore.add(ChatColor.GRAY + "Spread: " + ChatColor.GREEN + DECIMAL_FORMAT.format(data.getSpread() * 100) + "%" + ChatColor.GRAY + " (Max: "
|
||||
+ ChatColor.GREEN + DECIMAL_FORMAT.format(data.getMaxSpread() * 100) + "%" + ChatColor.GRAY + ")");
|
||||
|
||||
if (data.hasMin())
|
||||
lore.add(ChatColor.GRAY + "Min: " + ChatColor.GREEN + DECIMAL_FORMAT.format(data.getMin()));
|
||||
if (data.hasMax())
|
||||
lore.add(ChatColor.GRAY + "Max: " + ChatColor.GREEN + DECIMAL_FORMAT.format(data.getMax()));
|
||||
}
|
||||
} else
|
||||
lore.add(ChatColor.GRAY + "Current Value: " + ChatColor.GREEN + "---");
|
||||
|
||||
@ -347,7 +337,8 @@ public class DoubleStat extends ItemStat<NumericStatFormula, DoubleData> impleme
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull public DoubleData getClearStatData() {
|
||||
@NotNull
|
||||
public DoubleData getClearStatData() {
|
||||
return new DoubleData(0D);
|
||||
}
|
||||
|
||||
@ -406,7 +397,8 @@ public class DoubleStat extends ItemStat<NumericStatFormula, DoubleData> impleme
|
||||
}
|
||||
|
||||
public static class DoubleUpgradeInfo implements UpgradeInfo {
|
||||
@NotNull PlusMinusPercent pmp;
|
||||
@NotNull
|
||||
PlusMinusPercent pmp;
|
||||
|
||||
/**
|
||||
* Generate a <code>DoubleUpgradeInfo</code> from this <code><b>String</b></code>
|
||||
@ -414,10 +406,12 @@ public class DoubleStat extends ItemStat<NumericStatFormula, DoubleData> impleme
|
||||
* <p></p>
|
||||
* To keep older MMOItems versions working the same way, instead of having no prefix
|
||||
* to use the <i>set</i> function of the PMP, one must use an <b><code>s</code></b> prefix.
|
||||
*
|
||||
* @param obj A <code><u>String</u></code> that encodes for a PMP.
|
||||
* @throws IllegalArgumentException If any part of the operation goes wrong (including reading the PMP).
|
||||
*/
|
||||
@NotNull public static DoubleUpgradeInfo GetFrom(@Nullable Object obj) throws IllegalArgumentException {
|
||||
@NotNull
|
||||
public static DoubleUpgradeInfo GetFrom(@Nullable Object obj) throws IllegalArgumentException {
|
||||
|
||||
// Shall not be null
|
||||
Validate.notNull(obj, FriendlyFeedbackProvider.quickForConsole(FFPMMOItems.get(), "Upgrade operation must not be null"));
|
||||
@ -430,7 +424,12 @@ public class DoubleStat extends ItemStat<NumericStatFormula, DoubleData> impleme
|
||||
}
|
||||
|
||||
// Adapt to PMP format
|
||||
char c = str.charAt(0); if (c == 's') { str = str.substring(1); } else if (c != '+' && c != '-' && c != 'n') { str = '+' + str; }
|
||||
char c = str.charAt(0);
|
||||
if (c == 's') {
|
||||
str = str.substring(1);
|
||||
} else if (c != '+' && c != '-' && c != 'n') {
|
||||
str = '+' + str;
|
||||
}
|
||||
|
||||
// Is it a valid plus minus percent?
|
||||
FriendlyFeedbackProvider ffp = new FriendlyFeedbackProvider(FFPMMOItems.get());
|
||||
@ -444,12 +443,18 @@ public class DoubleStat extends ItemStat<NumericStatFormula, DoubleData> impleme
|
||||
return new DoubleUpgradeInfo(pmpRead);
|
||||
}
|
||||
|
||||
public DoubleUpgradeInfo(@NotNull PlusMinusPercent pmp) { this.pmp = pmp; }
|
||||
public DoubleUpgradeInfo(@NotNull PlusMinusPercent pmp) {
|
||||
this.pmp = pmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* The operation every level will perform.
|
||||
*
|
||||
* @see PlusMinusPercent
|
||||
*/
|
||||
@NotNull public PlusMinusPercent getPMP() { return pmp; }
|
||||
@NotNull
|
||||
public PlusMinusPercent getPMP() {
|
||||
return pmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user