mirror of
https://gitlab.com/phoenix-dvpmt/mmoitems.git
synced 2024-12-22 04:37:42 +01:00
Can now choose if a GemStone's stats are affected by Upgrading the item it is put onto.
This commit is contained in:
parent
4540bd4cfc
commit
9474dcddf3
2
pom.xml
2
pom.xml
@ -96,7 +96,7 @@
|
||||
<dependency>
|
||||
<groupId>io.lumine</groupId>
|
||||
<artifactId>MythicLib</artifactId>
|
||||
<version>1.0.9-SNAPSHOT</version>
|
||||
<version>1.0.10</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
@ -136,7 +136,7 @@ public class ItemStats {
|
||||
VANILLA_EATING_ANIMATION = new VanillaEatingAnimation(),
|
||||
INEDIBLE = new Inedible(),
|
||||
GEM_COLOR = new GemColor(),
|
||||
//todo GEM_UPGRADE_SCALING = new GemUpgradeScaling(),
|
||||
GEM_UPGRADE_SCALING = new GemUpgradeScaling(),
|
||||
ITEM_TYPE_RESTRICTION = new ItemTypeRestriction(),
|
||||
MAX_CONSUME = new DoubleStat("MAX_CONSUME", Material.BLAZE_POWDER, "Max Consume", new String[]{"Max amount of usage before", "item disappears."}, new String[]{"consumable"}),
|
||||
SUCCESS_RATE = new SuccessRate(),
|
||||
|
@ -37,10 +37,12 @@ import net.Indyuce.mmoitems.manager.*;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.File;
|
||||
@ -523,7 +525,7 @@ public class MMOItems extends LuminePlugin {
|
||||
setRPG(plugin.load());
|
||||
|
||||
// Mention it
|
||||
SLog("Using \u00a76" + plugin.getName() + "\u00a77 as RPG Player provider.");
|
||||
Log("Using \u00a76" + plugin.getName() + "\u00a77 as RPG Player provider.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -568,7 +570,7 @@ public class MMOItems extends LuminePlugin {
|
||||
* @return Generates an item given an item template with a
|
||||
* specific item level and item tier
|
||||
*/
|
||||
public ItemStack getItem(Type type, String id, int itemLevel, @Nullable ItemTier itemTier) {
|
||||
public ItemStack getItem(@NotNull Type type, @NotNull String id, int itemLevel, @Nullable ItemTier itemTier) {
|
||||
return getMMOItem(type, id, itemLevel, itemTier).newBuilder().build();
|
||||
}
|
||||
|
||||
@ -577,7 +579,7 @@ public class MMOItems extends LuminePlugin {
|
||||
* 0 and the item will have no item tier unless one is specified in
|
||||
* the base item data.
|
||||
*/
|
||||
public MMOItem getMMOItem(Type type, String id) {
|
||||
public MMOItem getMMOItem(@NotNull Type type, @NotNull String id) {
|
||||
return templateManager.getTemplate(type, id).newBuilder(0, null).build();
|
||||
}
|
||||
|
||||
@ -586,25 +588,21 @@ public class MMOItems extends LuminePlugin {
|
||||
* 0 and the item will have no item tier unless one is specified in
|
||||
* the base item data.
|
||||
*/
|
||||
public ItemStack getItem(Type type, String id) {
|
||||
public ItemStack getItem(@NotNull Type type, @NotNull String id) {
|
||||
return getMMOItem(type, id).newBuilder().build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs something into the console with a cool [MMOItems] prefix :)
|
||||
* <p></p>
|
||||
* Parses color codes. <b>Meant for DEV testing</b>, all of them are removed every release.
|
||||
* Parses color codes. <b>Mostly for DEV testing</b>. these may removed any release.
|
||||
*/
|
||||
public static void Log(String message) {
|
||||
plugin.getServer().getConsoleSender().sendMessage("\u00a78[" + ChatColor.YELLOW + "MMOItems\u00a78] \u00a77" + message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs something into the console with a cool [MMOItems] prefix :)
|
||||
* <p></p>
|
||||
* Parses color codes, official method. Wont be removed when releasing MMOItems versions.
|
||||
* @return The server's console sender.
|
||||
*/
|
||||
public static void SLog(String message) {
|
||||
plugin.getServer().getConsoleSender().sendMessage("\u00a78[" + ChatColor.YELLOW + "MMOItems\u00a78] \u00a77" + message);
|
||||
}
|
||||
@NotNull public static ConsoleCommandSender getConsole() { return plugin.getServer().getConsoleSender(); }
|
||||
}
|
@ -2,9 +2,15 @@ package net.Indyuce.mmoitems.api;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackCategory;
|
||||
import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackProvider;
|
||||
import net.Indyuce.mmoitems.ItemStats;
|
||||
import net.Indyuce.mmoitems.api.util.message.FriendlyFeedbackPalette_MMOItems;
|
||||
import net.Indyuce.mmoitems.stat.data.UpgradeData;
|
||||
import net.Indyuce.mmoitems.stat.data.type.Mergeable;
|
||||
import net.Indyuce.mmoitems.stat.data.type.StatData;
|
||||
import net.Indyuce.mmoitems.stat.type.StatHistory;
|
||||
@ -16,60 +22,147 @@ import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem;
|
||||
import net.Indyuce.mmoitems.stat.data.type.UpgradeInfo;
|
||||
import net.Indyuce.mmoitems.stat.type.ItemStat;
|
||||
import net.Indyuce.mmoitems.stat.type.Upgradable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class UpgradeTemplate {
|
||||
private final String id;
|
||||
private final Map<ItemStat, UpgradeInfo> stats = new HashMap<>();
|
||||
@NotNull private final String id;
|
||||
@NotNull private final Map<ItemStat, UpgradeInfo> perStatUpgradeInfos = new HashMap<>();
|
||||
|
||||
public UpgradeTemplate(ConfigurationSection config) {
|
||||
/**
|
||||
* Loads an Upgrade Template directly from the YML file. Neat!
|
||||
*/
|
||||
public UpgradeTemplate(@NotNull ConfigurationSection config) {
|
||||
Validate.notNull(config, "You must specify a config section.");
|
||||
|
||||
// Build ID
|
||||
id = config.getName().toLowerCase().replace("_", "-").replace(" ", "-");
|
||||
|
||||
// Feedback
|
||||
FriendlyFeedbackProvider ffp = new FriendlyFeedbackProvider(FriendlyFeedbackPalette_MMOItems.get());
|
||||
ffp.ActivatePrefix(true, "Upgrade Template $i&o" + config.getName());
|
||||
|
||||
// For ever stat
|
||||
for (String key : config.getKeys(false)) {
|
||||
|
||||
// Get internal stat ID
|
||||
String statFormat = key.toUpperCase().replace("-", "_");
|
||||
|
||||
// Attempt to find stat
|
||||
ItemStat stat = MMOItems.plugin.getStats().get(statFormat);
|
||||
Validate.notNull(stat, "Could not read stat ID " + statFormat);
|
||||
Validate.isTrue(stat instanceof Upgradable, "Stat " + stat.getId() + " us not upgradable.");
|
||||
if (stat == null) { ffp.Log(FriendlyFeedbackCategory.ERROR, "Stat '$r{0}$b' $fnot found$b.", statFormat); continue; }
|
||||
if (!(stat instanceof Upgradable)) { ffp.Log(FriendlyFeedbackCategory.ERROR, "Stat $r{0}$b is $fnot upgradeable$b.", stat.getId()); continue; }
|
||||
if (!(stat.getClearStatData() instanceof Mergeable)) { ffp.Log(FriendlyFeedbackCategory.ERROR, "Stat Data used by $r{0}$b is $fnot mergeable$b, and thus it cannot be upgradeable. Contact the dev of this ItemStat.", stat.getId()); continue; }
|
||||
|
||||
// Attempt to parse Upgrade Info
|
||||
try {
|
||||
stats.put(stat, ((Upgradable) stat).loadUpgradeInfo(config.get(key)));
|
||||
|
||||
// Parsed correctly? Add
|
||||
perStatUpgradeInfos.put(stat, ((Upgradable) stat).loadUpgradeInfo(config.get(key)));
|
||||
|
||||
// Somethings up, generate exception ig
|
||||
} catch (IllegalArgumentException exception) {
|
||||
MMOItems.plugin.getLogger().log(Level.WARNING,
|
||||
"An error occured while trying to load stat '" + key + "' from upgrade template '" + id + "': " + exception.getMessage());
|
||||
|
||||
// Log
|
||||
ffp.Log(FriendlyFeedbackCategory.ERROR, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Print all failures
|
||||
ffp.SendTo(FriendlyFeedbackCategory.ERROR, MMOItems.getConsole());
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
/**
|
||||
* Get the internal ID of this template.
|
||||
* <p></p>
|
||||
* In the format: <code><b>upgrade-template-name</b></code>
|
||||
* <p>(No spaces nor underscores, lowercase)</p>
|
||||
*/
|
||||
@NotNull public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Set<ItemStat> getKeys() {
|
||||
return stats.keySet();
|
||||
/**
|
||||
* Get the <code>ItemStat</code>s that this template has <code>UpgradeInfo</code> about.
|
||||
*/
|
||||
@NotNull public Set<ItemStat> getKeys() {
|
||||
return perStatUpgradeInfos.keySet();
|
||||
}
|
||||
|
||||
public UpgradeInfo getUpgradeInfo(ItemStat stat) {
|
||||
return stats.get(stat);
|
||||
/**
|
||||
* Get the <code>UpgradeInfo</code> associated with this stat.
|
||||
*/
|
||||
@Nullable public UpgradeInfo getUpgradeInfo(@NotNull ItemStat stat) {
|
||||
return perStatUpgradeInfos.get(stat);
|
||||
}
|
||||
|
||||
public void upgrade(MMOItem mmoitem) {
|
||||
for (ItemStat stat : stats.keySet()) {
|
||||
/**
|
||||
* Upgrades this MMOItem by 1 level
|
||||
*/
|
||||
public void upgrade(@NotNull MMOItem mmoitem) {
|
||||
|
||||
// Yes
|
||||
upgradeTo(mmoitem, mmoitem.getUpgradeLevel() + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrades this MMOItem's stats and sets the level.
|
||||
* @param level Target level, which may even be negative!
|
||||
*/
|
||||
public void upgradeTo(@NotNull MMOItem mmoitem, int level) {
|
||||
|
||||
// Set the items level
|
||||
UpgradeData dat;
|
||||
if (mmoitem.hasData(ItemStats.UPGRADE)) { dat = (UpgradeData) mmoitem.getData(ItemStats.UPGRADE); } else { dat = new UpgradeData(null, null, false, false, 0, 100); }
|
||||
dat.setLevel(level);
|
||||
mmoitem.setData(ItemStats.UPGRADE, dat);
|
||||
|
||||
// For every Stat-UpgradeInfo pair
|
||||
for (ItemStat stat : perStatUpgradeInfos.keySet()) {
|
||||
|
||||
// If it has the data to begin with?
|
||||
if (mmoitem.hasData(stat)) {
|
||||
|
||||
// ONLY if mergeable
|
||||
if (stat.getClearStatData() instanceof Mergeable) {
|
||||
// Initializes Stat History
|
||||
StatHistory<StatData> hist = StatHistory.From(mmoitem, stat);
|
||||
|
||||
// Initializes original stats.
|
||||
StatHistory.From(mmoitem, stat);
|
||||
}
|
||||
|
||||
// Applies changes
|
||||
((Upgradable) stat).apply(mmoitem, stats.get(stat));
|
||||
// The Stat History now manages applying upgrades.
|
||||
mmoitem.setData(stat, hist.Recalculate());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return If the user has set in the config that the stats should display how the item's upgrades have affected them.
|
||||
*/
|
||||
public static boolean isDisplayingUpgrades() { return MMOItems.plugin.getConfig().getBoolean("item-upgrading.display-stat-changes", false); }
|
||||
|
||||
/**
|
||||
* The user may define how to display stat changes due to upgrades,
|
||||
* as well as 'negative' and 'positive' colours.
|
||||
*
|
||||
* @return A string ready to just have its colors parsed and inserted into lore.
|
||||
* @param value The <code>toString()</code> of this will replace all instances of <code>#stat#</code> the user specifies in the config.
|
||||
* @param isNegative Should 'negative' coloration be used instead of positive? The user uses the color code <code><b>&p</b></code> in this place.
|
||||
*/
|
||||
@NotNull public static String getUpgradeChangeSuffix(@NotNull String value, boolean isNegative) {
|
||||
|
||||
// Get the base
|
||||
String base = Objects.requireNonNull(MMOItems.plugin.getConfig().getString("item-upgrading.stat-change-suffix", " &8(&p#stat#&8)"));
|
||||
String succ = Objects.requireNonNull(MMOItems.plugin.getConfig().getString("item-upgrading.stat-change-positive", "&a"));
|
||||
String fauc = Objects.requireNonNull(MMOItems.plugin.getConfig().getString("item-upgrading.stat-change-negative", "&c"));
|
||||
|
||||
// Parse ig
|
||||
if (isNegative) {
|
||||
|
||||
// Failure-colored
|
||||
return base.replace("&p", fauc).replace("#stat#", value);
|
||||
|
||||
// Its a positive upgrade-yo
|
||||
} else {
|
||||
|
||||
// Success-coloreds
|
||||
return base.replace("&p", succ).replace("#stat#", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,8 +8,10 @@ import net.Indyuce.mmoitems.api.event.item.ApplyGemStoneEvent;
|
||||
import net.Indyuce.mmoitems.api.item.mmoitem.LiveMMOItem;
|
||||
import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem;
|
||||
import net.Indyuce.mmoitems.api.util.message.Message;
|
||||
import net.Indyuce.mmoitems.stat.GemUpgradeScaling;
|
||||
import net.Indyuce.mmoitems.stat.data.GemSocketsData;
|
||||
import net.Indyuce.mmoitems.stat.data.GemstoneData;
|
||||
import net.Indyuce.mmoitems.stat.data.StringData;
|
||||
import net.Indyuce.mmoitems.stat.data.UpgradeData;
|
||||
import net.Indyuce.mmoitems.stat.data.type.Mergeable;
|
||||
import net.Indyuce.mmoitems.stat.data.type.StatData;
|
||||
@ -41,7 +43,8 @@ public class GemStone extends UseItem {
|
||||
String gemType = getNBTItem().getString(ItemStats.GEM_COLOR.getNBTPath());
|
||||
|
||||
GemSocketsData sockets = (GemSocketsData) targetMMO.getData(ItemStats.GEM_SOCKETS);
|
||||
if (!sockets.canReceive(gemType))
|
||||
String foundSocketColor = sockets.getEmptySocket(gemType);
|
||||
if (foundSocketColor == null)
|
||||
return new ApplyResult(ResultType.NONE);
|
||||
|
||||
/*
|
||||
@ -73,30 +76,47 @@ public class GemStone extends UseItem {
|
||||
* permanent effects. also REGISTER gem stone in the item gem stone
|
||||
* list.
|
||||
*/
|
||||
LiveMMOItem mmo = new LiveMMOItem(getNBTItem());
|
||||
GemstoneData gemData = new GemstoneData(mmo);
|
||||
LiveMMOItem gemMMOItem = new LiveMMOItem(getNBTItem());
|
||||
GemstoneData gemData = new GemstoneData(gemMMOItem, foundSocketColor);
|
||||
sockets.apply(gemType, gemData);
|
||||
//UPGRD//MMOItems. Log("Applying Gemstone: \u00a73" + foundSocketColor);
|
||||
|
||||
/*
|
||||
* Get the item's level, important for the GemScalingStat
|
||||
*/
|
||||
StatData upgradeLevel = targetMMO.getData(ItemStats.UPGRADE);
|
||||
if (upgradeLevel != null) { gemData.SetLevel(((UpgradeData) upgradeLevel).getLevel()); }
|
||||
Integer levelIdentified = null; String scaling = GemUpgradeScaling.SUBSEQUENT;
|
||||
if (gemMMOItem.hasData(ItemStats.GEM_UPGRADE_SCALING)) { scaling = gemMMOItem.getData(ItemStats.GEM_UPGRADE_SCALING).toString(); }
|
||||
//UPGRD//MMOItems. Log("Scaling Identified: \u00a73" + scaling);
|
||||
switch (scaling) {
|
||||
case GemUpgradeScaling.HISTORIC:
|
||||
levelIdentified = 0;
|
||||
break;
|
||||
case GemUpgradeScaling.SUBSEQUENT:
|
||||
StatData upgradeLevel = targetMMO.getData(ItemStats.UPGRADE);
|
||||
if (upgradeLevel != null) { levelIdentified = ((UpgradeData) upgradeLevel).getLevel(); }
|
||||
break;
|
||||
case GemUpgradeScaling.NEVER:
|
||||
default:
|
||||
levelIdentified = null;
|
||||
break;
|
||||
}
|
||||
gemData.setLevel(levelIdentified);
|
||||
//UPGRD//MMOItems. Log("Set Level: \u00a7b" + gemData.getLevel());
|
||||
|
||||
/*
|
||||
* Only applies NON PROPER and MERGEABLE item stats
|
||||
*/
|
||||
for (ItemStat stat : mmo.getStats()) {
|
||||
for (ItemStat stat : gemMMOItem.getStats()) {
|
||||
|
||||
// If it is not PROPER
|
||||
if (!(stat instanceof GemStoneStat)) {
|
||||
|
||||
// Get the stat data
|
||||
StatData data = mmo.getData(stat);
|
||||
StatData data = gemMMOItem.getData(stat);
|
||||
|
||||
// If the data is MERGEABLE
|
||||
if (data instanceof Mergeable) {
|
||||
//GEM//MMOItems.Log("\u00a79>>> \u00a77Gem-Merging \u00a7c" + stat.getNBTPath());
|
||||
//GEM////UPGRD//MMOItems. Log("\u00a79>>> \u00a77Gem-Merging \u00a7c" + stat.getNBTPath());
|
||||
|
||||
// Merge into it
|
||||
targetMMO.mergeData(stat, data, gemData.getHistoricUUID());
|
||||
|
@ -9,6 +9,7 @@ import io.lumine.mythic.utils.adventure.text.Component;
|
||||
import net.Indyuce.mmoitems.ItemStats;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.api.Type;
|
||||
import net.Indyuce.mmoitems.api.UpgradeTemplate;
|
||||
import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem;
|
||||
import net.Indyuce.mmoitems.api.item.util.DynamicLore;
|
||||
import net.Indyuce.mmoitems.api.util.StatFormat;
|
||||
@ -112,8 +113,8 @@ public class ItemStackBuilder {
|
||||
* @return Returns built NBTItem with applied tags and lore
|
||||
*/
|
||||
public NBTItem buildNBT() {
|
||||
this.mmoitem = new StatLore(mmoitem).generateNewItem();
|
||||
|
||||
// Clone as to not conflict in any way
|
||||
this.mmoitem = mmoitem.clone();
|
||||
//GEM//MMOItems.Log("\u00a7e+ \u00a77Building \u00a7c" + mmoitem.getType().getName() + " " + mmoitem.getId() + "\u00a77 (Size \u00a7e" + mmoitem.mergeableStatHistory.size() + "\u00a77 Historic)");
|
||||
|
||||
// For every stat within this item
|
||||
@ -202,45 +203,4 @@ public class ItemStackBuilder {
|
||||
public ItemStack build() {
|
||||
return new DynamicLore(buildNBT()).build();
|
||||
}
|
||||
|
||||
//
|
||||
public class StatLore {
|
||||
private MMOItem mmoitem;
|
||||
|
||||
public StatLore(MMOItem mmoitem) {
|
||||
this.mmoitem = mmoitem;
|
||||
}
|
||||
|
||||
public MMOItem generateNewItem() {
|
||||
mmoitem = mmoitem.clone();
|
||||
|
||||
if (MMOItems.plugin.getConfig().getBoolean("item-upgrading.display-stat-changes", false))
|
||||
for (ItemStat stat : mmoitem.getStats()) {
|
||||
StatHistory<StatData> data = mmoitem.getStatHistory(stat);
|
||||
if (data != null
|
||||
&& data.getOriginalData() instanceof DoubleData
|
||||
&& mmoitem.getData(stat) instanceof DoubleData) {
|
||||
double value, original, current;
|
||||
try {
|
||||
original = ((DoubleData) data.getOriginalData()).getValue();
|
||||
current = ((DoubleData) mmoitem.getData(stat)).getValue();
|
||||
value = current - original;
|
||||
} catch (NullPointerException e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (value != 0) {
|
||||
lore.insert(stat.getPath(), stat.formatNumericStat(value, "#",
|
||||
new StatFormat("##").format(current))
|
||||
+ MythicLib.plugin.parseColors(MMOItems.plugin.getConfig()
|
||||
.getString("item-upgrading.stat-change-suffix", " &e(+#stat#)").replace(
|
||||
"#stat#", new StatFormat("##").format(value))));
|
||||
}
|
||||
}
|
||||
}
|
||||
return mmoitem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,10 +1,13 @@
|
||||
package net.Indyuce.mmoitems.api.item.mmoitem;
|
||||
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.ItemStats;
|
||||
import net.Indyuce.mmoitems.api.Type;
|
||||
import net.Indyuce.mmoitems.api.UpgradeTemplate;
|
||||
import net.Indyuce.mmoitems.api.item.ItemReference;
|
||||
import net.Indyuce.mmoitems.api.item.build.ItemStackBuilder;
|
||||
import net.Indyuce.mmoitems.stat.data.GemSocketsData;
|
||||
import net.Indyuce.mmoitems.stat.data.GemstoneData;
|
||||
import net.Indyuce.mmoitems.stat.data.UpgradeData;
|
||||
import net.Indyuce.mmoitems.stat.data.type.Mergeable;
|
||||
import net.Indyuce.mmoitems.stat.data.type.StatData;
|
||||
import net.Indyuce.mmoitems.stat.type.ItemStat;
|
||||
@ -13,10 +16,7 @@ import org.apache.commons.lang.Validate;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
|
||||
public class MMOItem implements ItemReference {
|
||||
private final Type type;
|
||||
@ -83,17 +83,8 @@ public class MMOItem implements ItemReference {
|
||||
sHistory.registerExternalData(data);
|
||||
}
|
||||
|
||||
// Merge or set onto main stat
|
||||
if (hasData(stat)) {
|
||||
|
||||
// Merge
|
||||
((Mergeable) getData(stat)).merge(data);
|
||||
|
||||
} else {
|
||||
|
||||
// Override Completely
|
||||
setData(stat, data);
|
||||
}
|
||||
// Recalculate
|
||||
setData(stat, sHistory.Recalculate());
|
||||
|
||||
// Merging means replacing if it cannot be merged
|
||||
} else {
|
||||
@ -115,7 +106,7 @@ public class MMOItem implements ItemReference {
|
||||
stats.remove(stat);
|
||||
}
|
||||
|
||||
@Nullable public StatData getData(@NotNull ItemStat stat) {
|
||||
public StatData getData(@NotNull ItemStat stat) {
|
||||
return stats.get(stat);
|
||||
}
|
||||
|
||||
@ -199,4 +190,91 @@ public class MMOItem implements ItemReference {
|
||||
mergeableStatHistory.put(stat.getNBTPath(), hist);
|
||||
}
|
||||
//endregion
|
||||
|
||||
//region Upgrading API
|
||||
/**
|
||||
* Upgrades this MMOItem one level.
|
||||
* <p></p>
|
||||
* <b>Make sure to check {@link #hasUpgradeTemplate()} before calling.</b>
|
||||
*/
|
||||
public void upgrade() {
|
||||
|
||||
// Upgrade through the template's API
|
||||
getUpgradeTemplate().upgrade(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this item has all the information
|
||||
* required to call
|
||||
*/
|
||||
public boolean hasUpgradeTemplate() {
|
||||
|
||||
// Does it have Upgrade Stat?
|
||||
if (hasData(ItemStats.UPGRADE)) {
|
||||
|
||||
// Get that data
|
||||
UpgradeData data = (UpgradeData) getData(ItemStats.UPGRADE);
|
||||
|
||||
// A template its all that's required
|
||||
return data.getTemplate() != null;
|
||||
}
|
||||
|
||||
// Nope
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The upgrade level, or 0 if there is none.
|
||||
*/
|
||||
public int getUpgradeLevel() {
|
||||
|
||||
// Does it have Upgrade Data?
|
||||
if (hasData(ItemStats.UPGRADE)) {
|
||||
|
||||
// Return the registered level.
|
||||
return ((UpgradeData) getData(ItemStats.UPGRADE)).getLevel();
|
||||
}
|
||||
|
||||
// Nope? Well its level 0 I guess.
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Make sure to check {@link #hasUpgradeTemplate()} before calling.</b>
|
||||
* <p></p>
|
||||
* This will fail and throw an exception if the MMOItem has no upgrade template.
|
||||
* @return The upgrade template by which the MMOItem would upgrade normally.
|
||||
*/
|
||||
@NotNull public UpgradeTemplate getUpgradeTemplate() {
|
||||
Validate.isTrue(hasUpgradeTemplate(), "This item has no Upgrade Information, do not call this method without checking first!");
|
||||
|
||||
// All Right
|
||||
UpgradeData data = (UpgradeData) getData(ItemStats.UPGRADE);
|
||||
|
||||
// That's the template
|
||||
return data.getTemplate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of GemStones inserted into this item
|
||||
*/
|
||||
@NotNull public Set<GemstoneData> getGemStones() {
|
||||
|
||||
// Got gem sockets?
|
||||
if (hasData(ItemStats.GEM_SOCKETS)) {
|
||||
|
||||
// Get Data
|
||||
GemSocketsData data = (GemSocketsData) getData(ItemStats.GEM_SOCKETS);
|
||||
|
||||
// Thats it
|
||||
return data.getGemstones();
|
||||
|
||||
// Has no gem sockets
|
||||
} else {
|
||||
|
||||
// Empty Set
|
||||
return new HashSet<>();
|
||||
}
|
||||
}
|
||||
//endregion
|
||||
}
|
||||
|
@ -0,0 +1,43 @@
|
||||
package net.Indyuce.mmoitems.api.util.message;
|
||||
|
||||
import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackPalette;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* ' Presentation '
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class FriendlyFeedbackPalette_MMOItems extends FriendlyFeedbackPalette {
|
||||
|
||||
/*
|
||||
* The instance of this palette :p
|
||||
*/
|
||||
FriendlyFeedbackPalette_MMOItems() {}
|
||||
@NotNull static FriendlyFeedbackPalette_MMOItems instance = new FriendlyFeedbackPalette_MMOItems();
|
||||
@NotNull public static FriendlyFeedbackPalette_MMOItems get() { return instance; }
|
||||
|
||||
@NotNull @Override public String getBodyFormat() { return "§x§a§5§b§5§a§7"; }
|
||||
@NotNull @Override public String consoleBodyFormat() { return ChatColor.GRAY.toString(); }
|
||||
|
||||
@NotNull @Override public String getExampleFormat() { return "§x§e§0§f§5§9§3"; }
|
||||
@NotNull @Override public String consoleExampleFormat() { return ChatColor.YELLOW.toString(); }
|
||||
|
||||
@NotNull @Override public String getInputFormat() { return"§x§7§d§c§7§5§8"; }
|
||||
@NotNull @Override public String consoleInputFormat() { return ChatColor.GREEN.toString(); }
|
||||
|
||||
@NotNull @Override public String getResultFormat() { return "§x§5§c§e§0§0§4"; }
|
||||
@NotNull @Override public String consoleResultFormat() { return ChatColor.GREEN.toString(); }
|
||||
|
||||
@NotNull @Override public String getSuccessFormat() { return "§x§2§5§f§7§c§6"; }
|
||||
@NotNull @Override public String consoleSuccessFormat() { return ChatColor.AQUA.toString(); }
|
||||
|
||||
@NotNull @Override public String getFailureFormat() { return "§x§f§f§6§0§2§6"; }
|
||||
@NotNull @Override public String consoleFailureFormat() { return ChatColor.RED.toString(); }
|
||||
|
||||
@NotNull @Override public String getRawPrefix() { return "§8[§eMMOItems#s§8] "; }
|
||||
@NotNull @Override public String getRawPrefixConsole() { return "§8[§eMMOItems#s§8] "; }
|
||||
|
||||
@NotNull @Override public String getSubdivisionFormat() { return "§x§c§c§a§3§3§3§o"; }
|
||||
@NotNull @Override public String consoleSubdivisionFormat() { return "§6§o"; }
|
||||
}
|
@ -4,6 +4,8 @@ import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.api.ConfigFile;
|
||||
import net.Indyuce.mmoitems.api.UpgradeTemplate;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
@ -33,7 +35,11 @@ public class UpgradeManager implements Reloadable {
|
||||
return templates.values();
|
||||
}
|
||||
|
||||
public UpgradeTemplate getTemplate(String id) {
|
||||
/**
|
||||
* Get the <code>UpgradeTemplate</code> of this name.
|
||||
* @return <code>null</code> if there is no such template loaded.
|
||||
*/
|
||||
@Nullable public UpgradeTemplate getTemplate(@NotNull String id) {
|
||||
return templates.get(id);
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,12 @@
|
||||
package net.Indyuce.mmoitems.stat;
|
||||
|
||||
import net.Indyuce.mmoitems.stat.data.StringData;
|
||||
import net.Indyuce.mmoitems.stat.data.type.StatData;
|
||||
import net.Indyuce.mmoitems.stat.type.ChooseStat;
|
||||
import net.Indyuce.mmoitems.stat.type.GemStoneStat;
|
||||
import io.lumine.mythic.lib.version.VersionMaterial;
|
||||
import org.bukkit.Material;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@ -34,4 +37,6 @@ public class GemUpgradeScaling extends ChooseStat implements GemStoneStat {
|
||||
// Update
|
||||
HintChooseableDefs(definitions);
|
||||
}
|
||||
|
||||
@NotNull @Override public StatData getClearStatData() { return new StringData(SUBSEQUENT); }
|
||||
}
|
||||
|
@ -43,12 +43,12 @@ public class ItemSetStat extends StringStat {
|
||||
@Override
|
||||
public void whenApplied(@NotNull ItemStackBuilder item, @NotNull StatData data) {
|
||||
|
||||
// Add NBT
|
||||
item.addItemTag(getAppliedNBT(data));
|
||||
|
||||
// Display in lore
|
||||
ItemSet set = MMOItems.plugin.getSets().get(data.toString());
|
||||
item.getLore().insert("set", set.getLoreTag());
|
||||
|
||||
// Add NBT
|
||||
item.addItemTag(getAppliedNBT(data));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
@ -166,7 +166,7 @@ public class UpgradeStat extends ItemStat implements ConsumableItemInteraction {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public StatData getClearStatData() { return new UpgradeData("", "", false, false, 0, 0D); }
|
||||
public StatData getClearStatData() { return new UpgradeData(null, null, false, false, 0, 0D); }
|
||||
|
||||
@Override
|
||||
public boolean handleConsumableEffect(InventoryClickEvent event, PlayerData playerData, Consumable consumable, NBTItem target, Type targetType) {
|
||||
|
@ -5,6 +5,7 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import io.lumine.mythic.lib.api.util.Ref;
|
||||
import net.Indyuce.mmoitems.api.interaction.GemStone;
|
||||
import org.apache.commons.lang.Validate;
|
||||
|
||||
@ -17,20 +18,31 @@ import net.Indyuce.mmoitems.stat.data.random.RandomStatData;
|
||||
import net.Indyuce.mmoitems.stat.data.type.Mergeable;
|
||||
import net.Indyuce.mmoitems.stat.data.type.StatData;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class GemSocketsData implements StatData, Mergeable, RandomStatData {
|
||||
private final Set<GemstoneData> gems = new HashSet<>();
|
||||
private final List<String> emptySlots;
|
||||
@NotNull private final Set<GemstoneData> gems = new HashSet<>();
|
||||
@NotNull private final List<String> emptySlots;
|
||||
|
||||
public GemSocketsData(List<String> emptySlots) {
|
||||
public GemSocketsData(@NotNull List<String> emptySlots) {
|
||||
this.emptySlots = emptySlots;
|
||||
}
|
||||
|
||||
public boolean canReceive(String gem) {
|
||||
/**
|
||||
* Attempts to find a slot of the same color of this gem within the item.
|
||||
* <p></p>
|
||||
* To know the color of the socket pass the same argument to {@link #getEmptySocket(String)}
|
||||
* which checks in the same order as this method for the first success.
|
||||
*/
|
||||
public boolean canReceive(@NotNull String gem) {
|
||||
return getEmptySocket(gem) != null;
|
||||
}
|
||||
|
||||
public String getEmptySocket(String gem) {
|
||||
/**
|
||||
* Get the first emtpty gem socket that matches this color
|
||||
* @return <code>null</code> if none matched.
|
||||
*/
|
||||
@Nullable public String getEmptySocket(@NotNull String gem) {
|
||||
for (String slot : emptySlots)
|
||||
if (gem.equals("") || slot.equals(MMOItems.plugin.getConfig().getString("gem-sockets.uncolored")) || gem.equals(slot))
|
||||
return slot;
|
||||
@ -50,11 +62,11 @@ public class GemSocketsData implements StatData, Mergeable, RandomStatData {
|
||||
emptySlots.add(slot);
|
||||
}
|
||||
|
||||
public List<String> getEmptySlots() {
|
||||
@NotNull public List<String> getEmptySlots() {
|
||||
return emptySlots;
|
||||
}
|
||||
|
||||
public Set<GemstoneData> getGemstones() {
|
||||
@NotNull public Set<GemstoneData> getGemstones() {
|
||||
return gems;
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,12 @@
|
||||
package net.Indyuce.mmoitems.stat.data;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.Indyuce.mmoitems.ItemStats;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.MMOUtils;
|
||||
import net.Indyuce.mmoitems.api.item.mmoitem.LiveMMOItem;
|
||||
import net.Indyuce.mmoitems.stat.GemUpgradeScaling;
|
||||
import net.Indyuce.mmoitems.stat.type.ItemStat;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -21,10 +18,10 @@ public class GemstoneData {
|
||||
@NotNull private final List<PotionEffectData> effects = new ArrayList<>();
|
||||
@NotNull private final Map<ItemStat, Double> stats = new HashMap<>();
|
||||
@NotNull private final String name;
|
||||
int levelPut = 0;
|
||||
@Nullable Integer levelPut = 0;
|
||||
@NotNull final UUID historicUUID;
|
||||
|
||||
@Nullable final String mmoitemType, mmoitemID;
|
||||
@Nullable final String mmoitemType, mmoitemID, socketColor;
|
||||
|
||||
/**
|
||||
* This constructor is not really performance friendly. It should only be
|
||||
@ -59,19 +56,21 @@ public class GemstoneData {
|
||||
mmoitemID = object.get("Id").getAsString();
|
||||
|
||||
JsonElement level = object.get("Level");
|
||||
if (level != null) { levelPut = level.getAsInt(); }
|
||||
|
||||
} else { historicUUID = UUID.randomUUID(); mmoitemID = null; mmoitemType = null; }
|
||||
if (level != null && level.isJsonPrimitive()) { levelPut = level.getAsJsonPrimitive().getAsInt(); } else { levelPut = null; }
|
||||
|
||||
JsonElement color = object.get("Color");
|
||||
if (color != null && color.isJsonPrimitive()) { socketColor = color.getAsJsonPrimitive().getAsString(); } else { socketColor = null; }
|
||||
|
||||
} else { historicUUID = UUID.randomUUID(); mmoitemID = null; mmoitemType = null; socketColor = null; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a GemStoneData from a GemStone MMOItem.
|
||||
* <p></p>
|
||||
* Basically extracts all the useable stats from the MMOItem, to have them ready to apply onto another MMOItem.
|
||||
* @param color Color of the slot this gem was inserted onto.
|
||||
*/
|
||||
public GemstoneData(@NotNull LiveMMOItem gemStoneMMOItem) {
|
||||
public GemstoneData(@NotNull LiveMMOItem gemStoneMMOItem, @Nullable String color) {
|
||||
|
||||
// Get Name to Display
|
||||
name = MMOUtils.getDisplayName(gemStoneMMOItem.getNBT().getItem());
|
||||
@ -87,6 +86,7 @@ public class GemstoneData {
|
||||
historicUUID = UUID.randomUUID();
|
||||
mmoitemID = gemStoneMMOItem.getId();
|
||||
mmoitemType = gemStoneMMOItem.getType().getId();
|
||||
socketColor = color;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -101,32 +101,42 @@ public class GemstoneData {
|
||||
this.name = name;
|
||||
mmoitemID = null;
|
||||
mmoitemType = null;
|
||||
socketColor = null;
|
||||
historicUUID = UUID.randomUUID();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is at which level (of the item) the gemstone was placed onto the item.
|
||||
* <p>A null level means this gem does not scale.</p>
|
||||
* <p></p>
|
||||
* For scaling purposes of stat {@link GemUpgradeScaling}
|
||||
*/
|
||||
public void SetLevel(int l) { levelPut = l; }
|
||||
public void setLevel(@Nullable Integer l) { levelPut = l; }
|
||||
/**
|
||||
* This is at which level (of the item) the gemstone was placed onto the item.
|
||||
* <p>A null level means this gem does not scale.</p>
|
||||
* <p></p>
|
||||
* For scaling purposes of stat {@link GemUpgradeScaling}
|
||||
*/
|
||||
public int GetLevel() { return levelPut; }
|
||||
@Nullable public Integer getLevel() { return levelPut; }
|
||||
|
||||
/**
|
||||
* Does this gem scale with item upgrades?
|
||||
*/
|
||||
public boolean isScaling() { return levelPut != null; }
|
||||
|
||||
/**
|
||||
* This is a completely empty builder.
|
||||
* <p></p>
|
||||
* You may add whatever you want with <code>addAbility()</code>,<code>addPermamentEffect</code>, or most widely usedly, <code>setStat()</code>.
|
||||
* @param name Name to display in the lore of the item when you put the gemstone into it.
|
||||
* @param color Color of the socket this gem is inserted onto
|
||||
*/
|
||||
public GemstoneData(@NotNull String name, @Nullable String type, @Nullable String id) {
|
||||
public GemstoneData(@NotNull String name, @Nullable String type, @Nullable String id, @Nullable String color) {
|
||||
this.name = name;
|
||||
mmoitemID = type;
|
||||
mmoitemType = id;
|
||||
socketColor = color;
|
||||
historicUUID = UUID.randomUUID();
|
||||
}
|
||||
|
||||
|
@ -11,15 +11,23 @@ import net.Indyuce.mmoitems.stat.data.type.StatData;
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A class containing the Upgrading stuff of an item. Things like:
|
||||
* <p> • What level it currently is
|
||||
* </p> • What upgrade template it upgrades with
|
||||
* <p> • Chance of successful upgrade
|
||||
* </p> • May it get destroyed if unsucessful upgrade?
|
||||
*/
|
||||
public class UpgradeData implements StatData, RandomStatData {
|
||||
private final String reference, template;
|
||||
@Nullable private final String reference, template;
|
||||
private final boolean workbench, destroy;
|
||||
private final double success;
|
||||
private final int max;
|
||||
private int level;
|
||||
|
||||
public UpgradeData(@NotNull String referenc, @NotNull String templat, boolean workbenc, boolean destro, int maxx, double succes) {
|
||||
public UpgradeData(@Nullable String referenc, @Nullable String templat, boolean workbenc, boolean destro, int maxx, double succes) {
|
||||
reference = referenc;
|
||||
template = templat;
|
||||
workbench = workbenc;
|
||||
@ -47,13 +55,22 @@ public class UpgradeData implements StatData, RandomStatData {
|
||||
success = object.get("Success").getAsDouble();
|
||||
}
|
||||
|
||||
public UpgradeTemplate getTemplate() {
|
||||
/**
|
||||
* @return The template associated to this data, if it is loaded.
|
||||
*/
|
||||
@Nullable public UpgradeTemplate getTemplate() {
|
||||
return MMOItems.plugin.getUpgrades().getTemplate(template);
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
public int getLevel() { return level; }
|
||||
|
||||
/**
|
||||
* Dont you mean {@link UpgradeTemplate#upgradeTo(MMOItem, int)}?
|
||||
* This sets the level the item thinks it is, does not apply no changes.
|
||||
* <p></p>
|
||||
* <b>Make sure you know what you are doing before using this</b>
|
||||
*/
|
||||
public void setLevel(int l) { level = l; }
|
||||
|
||||
public int getMaxUpgrades() {
|
||||
return max;
|
||||
@ -75,13 +92,22 @@ public class UpgradeData implements StatData, RandomStatData {
|
||||
return reference == null || data.reference == null || reference.isEmpty() || data.reference.isEmpty() || reference.equals(data.reference);
|
||||
}
|
||||
|
||||
public void upgrade(MMOItem mmoitem) {
|
||||
if (!MMOItems.plugin.getUpgrades().hasTemplate(template)) {
|
||||
/**
|
||||
* Upgrade this MMOItem by 1 Level
|
||||
*/
|
||||
public void upgrade(@NotNull MMOItem mmoitem) {
|
||||
|
||||
/*
|
||||
* Find Upgrade Template
|
||||
*/
|
||||
if (getTemplate() == null) {
|
||||
MMOItems.plugin.getLogger().warning("Couldn't find upgrade template '" + template + "'. Does it exist?");
|
||||
return;
|
||||
}
|
||||
|
||||
// change display name
|
||||
/*
|
||||
* Display Upgrade Level
|
||||
*/
|
||||
String suffix = MythicLib.plugin.parseColors(MMOItems.plugin.getConfig().getString("item-upgrading.name-suffix"));
|
||||
if (MMOItems.plugin.getConfig().getBoolean("item-upgrading.display-in-name"))
|
||||
if (mmoitem.hasData(ItemStats.NAME)) {
|
||||
@ -89,7 +115,6 @@ public class UpgradeData implements StatData, RandomStatData {
|
||||
nameData.setString(level == 0 ? nameData.toString() + suffix.replace("#lvl#", "" + (level + 1))
|
||||
: nameData.toString().replace(suffix.replace("#lvl#", "" + level), suffix.replace("#lvl#", "" + (level + 1))));
|
||||
}
|
||||
|
||||
/*TODO: implement this as a new dynamic lore type
|
||||
else if (mmoitem.hasData(ItemStats.LORE)) {
|
||||
StringListData loreData = (StringListData) mmoitem.getData(ItemStats.LORE);
|
||||
@ -101,11 +126,10 @@ public class UpgradeData implements StatData, RandomStatData {
|
||||
});
|
||||
}*/
|
||||
|
||||
// apply stat updates
|
||||
/*
|
||||
* Go through every stat that must be ugpraded and apply
|
||||
*/
|
||||
getTemplate().upgrade(mmoitem);
|
||||
|
||||
// increase the level
|
||||
level++;
|
||||
}
|
||||
|
||||
public JsonObject toJson() {
|
||||
|
@ -1,7 +1,15 @@
|
||||
package net.Indyuce.mmoitems.stat.data.type;
|
||||
|
||||
import net.Indyuce.mmoitems.stat.type.StatHistory;
|
||||
import net.Indyuce.mmoitems.stat.type.Upgradable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Most intuitive use is for ItemStats to not completely replace each other
|
||||
* when used through Gem Stones. However, this serves a crucial internal
|
||||
* role in determining which stats generate {@link StatHistory}es, which in
|
||||
* turn allows them to be {@link Upgradable}.
|
||||
*/
|
||||
public interface Mergeable {
|
||||
|
||||
/**
|
||||
|
@ -1,4 +1,6 @@
|
||||
package net.Indyuce.mmoitems.stat.data.type;
|
||||
|
||||
public interface UpgradeInfo {
|
||||
}
|
||||
/**
|
||||
* Parsed from the configs into providing a StatData all the changes each upgrade will give it.
|
||||
*/
|
||||
public interface UpgradeInfo { }
|
||||
|
@ -44,21 +44,4 @@ public abstract class AttributeStat extends DoubleStat {
|
||||
public double getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only difference from <code>DoubleStat.whenApplied()</code> is that
|
||||
* double stats dont bother displaying when equal to 0, but attribute
|
||||
* stats do.
|
||||
*/
|
||||
@Override public void whenApplied(@NotNull ItemStackBuilder item, @NotNull StatData data) {
|
||||
|
||||
// Get its value
|
||||
double value = ((DoubleData) data).getValue();
|
||||
|
||||
// Adds the Item Tag
|
||||
item.addItemTag(getAppliedNBT(data));
|
||||
|
||||
// Translates in Lore
|
||||
item.getLore().insert(getPath(), formatNumericStat(value, "#", new StatFormat("##").format(value)));
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,23 @@
|
||||
package net.Indyuce.mmoitems.stat.type;
|
||||
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.item.ItemTag;
|
||||
import io.lumine.mythic.lib.api.item.SupportedNBTTagValues;
|
||||
import io.lumine.mythic.lib.api.util.AltChar;
|
||||
import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackCategory;
|
||||
import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackMessage;
|
||||
import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackProvider;
|
||||
import io.lumine.mythic.lib.api.util.ui.PlusMinusPercent;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.MMOUtils;
|
||||
import net.Indyuce.mmoitems.api.UpgradeTemplate;
|
||||
import net.Indyuce.mmoitems.api.edition.StatEdition;
|
||||
import net.Indyuce.mmoitems.api.item.build.ItemStackBuilder;
|
||||
import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem;
|
||||
import net.Indyuce.mmoitems.api.item.mmoitem.ReadMMOItem;
|
||||
import net.Indyuce.mmoitems.api.util.NumericStatFormula;
|
||||
import net.Indyuce.mmoitems.api.util.StatFormat;
|
||||
import net.Indyuce.mmoitems.api.util.message.FriendlyFeedbackPalette_MMOItems;
|
||||
import net.Indyuce.mmoitems.gui.edition.EditionInventory;
|
||||
import net.Indyuce.mmoitems.stat.data.DoubleData;
|
||||
import net.Indyuce.mmoitems.stat.data.random.RandomStatData;
|
||||
@ -28,6 +35,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@ -50,6 +58,12 @@ public class DoubleStat extends ItemStat implements Upgradable {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 true; }
|
||||
|
||||
@Override
|
||||
public RandomStatData whenInitialized(Object object) {
|
||||
|
||||
@ -68,15 +82,65 @@ public class DoubleStat extends ItemStat implements Upgradable {
|
||||
// Get Value
|
||||
double value = ((DoubleData) data).getValue();
|
||||
|
||||
// Cancel if it equals ZERO, or its NEGATIVE and this doesnt support negative stats.
|
||||
// Cancel if it its NEGATIVE and this doesn't support negative stats.
|
||||
if (value < 0 && !handleNegativeStats()) { return; }
|
||||
|
||||
// Identify the upgrade amount
|
||||
double upgradeShift = 0;
|
||||
|
||||
// Displaying upgrades?
|
||||
if (UpgradeTemplate.isDisplayingUpgrades() && item.getMMOItem().getUpgradeLevel() != 0) {
|
||||
|
||||
// Get stat history
|
||||
StatHistory<StatData> hist = item.getMMOItem().getStatHistory(this);
|
||||
if (hist != null) {
|
||||
|
||||
// Get as if it had never been upgraded
|
||||
DoubleData uData = (DoubleData) hist.Recalculate_Unupgraded();
|
||||
|
||||
// Calculate Difference
|
||||
upgradeShift = value - uData.getValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Display if not ZERO
|
||||
if (value != 0) { item.getLore().insert(getPath(), formatNumericStat(value, "#", new StatFormat("##").format(value))); }
|
||||
if (value != 0 || upgradeShift != 0) {
|
||||
|
||||
// Displaying upgrades?
|
||||
if (upgradeShift != 0) {
|
||||
|
||||
item.getLore().insert(getPath(), formatNumericStat(value, "#", new StatFormat("##").format(value))
|
||||
+ MythicLib.plugin.parseColors(UpgradeTemplate.getUpgradeChangeSuffix(plus(upgradeShift) + (new StatFormat("##").format(upgradeShift)), !isGood(upgradeShift))));
|
||||
|
||||
} else {
|
||||
|
||||
// Just display normally
|
||||
item.getLore().insert(getPath(), formatNumericStat(value, "#", new StatFormat("##").format(value)));
|
||||
}
|
||||
}
|
||||
|
||||
// Add NBT Path
|
||||
item.addItemTag(getAppliedNBT(data));
|
||||
}
|
||||
@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).
|
||||
* <p>However, its not impossible for a stat to be evil instead, who knows?
|
||||
* <p></p>
|
||||
* This will return true if:
|
||||
* <p> > The amount is positive, and more benefits the player
|
||||
* </p> > The amount is negative, and more hurts the player
|
||||
*/
|
||||
public boolean isGood(double amount) {
|
||||
if (moreIsBetter()) {
|
||||
return amount >= 0;
|
||||
} else {
|
||||
return amount <= 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ArrayList<ItemTag> getAppliedNBT(@NotNull StatData data) {
|
||||
|
||||
@ -146,7 +210,7 @@ public class DoubleStat extends ItemStat implements Upgradable {
|
||||
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
|
||||
@ -165,7 +229,7 @@ public class DoubleStat extends ItemStat implements Upgradable {
|
||||
spread = MMOUtils.truncation(.8 * maxSpread, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Newest system with gaussian values calculation
|
||||
*/
|
||||
else {
|
||||
@ -215,45 +279,104 @@ public class DoubleStat extends ItemStat implements Upgradable {
|
||||
return new DoubleData(0D);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public UpgradeInfo loadUpgradeInfo(Object obj) {
|
||||
return new DoubleUpgradeInfo(obj);
|
||||
public UpgradeInfo loadUpgradeInfo(@Nullable Object obj) throws IllegalArgumentException {
|
||||
|
||||
// Return result of thay
|
||||
return DoubleUpgradeInfo.GetFrom(obj);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public void apply(MMOItem mmoitem, UpgradeInfo info) {
|
||||
DoubleUpgradeInfo doubleInfo = (DoubleUpgradeInfo) info;
|
||||
public StatData apply(@NotNull StatData original, @NotNull UpgradeInfo info, int level) {
|
||||
|
||||
if (mmoitem.hasData(this)) {
|
||||
if (doubleInfo.isRelative())
|
||||
((DoubleData) mmoitem.getData(this)).addRelative(doubleInfo.getAmount());
|
||||
else
|
||||
((DoubleData) mmoitem.getData(this)).add(doubleInfo.getAmount());
|
||||
} else
|
||||
mmoitem.setData(this, new DoubleData(doubleInfo.getAmount()));
|
||||
// Must be DoubleData
|
||||
if (original instanceof DoubleData && info instanceof DoubleUpgradeInfo) {
|
||||
|
||||
// Get value
|
||||
double value = ((DoubleData) original).getValue();
|
||||
|
||||
// If leveling up
|
||||
if (level > 0) {
|
||||
|
||||
// While still positive
|
||||
while (level > 0) {
|
||||
|
||||
// Apply PMP Operation Positively
|
||||
value = ((DoubleUpgradeInfo) info).getPMP().apply(value);
|
||||
|
||||
// Decrease
|
||||
level--;
|
||||
}
|
||||
|
||||
// Degrading the item
|
||||
} else if (level < 0) {
|
||||
|
||||
// While still negative
|
||||
while (level < 0) {
|
||||
|
||||
// Apply PMP Operation Reversibly
|
||||
value = ((DoubleUpgradeInfo) info).getPMP().reverse(value);
|
||||
|
||||
// Decrease
|
||||
level++;
|
||||
}
|
||||
}
|
||||
|
||||
// Update
|
||||
((DoubleData) original).setValue(value);
|
||||
}
|
||||
|
||||
// Upgraded
|
||||
return original;
|
||||
}
|
||||
|
||||
public static class DoubleUpgradeInfo implements UpgradeInfo {
|
||||
private final boolean relative;
|
||||
private final double amount;
|
||||
@NotNull PlusMinusPercent pmp;
|
||||
|
||||
public DoubleUpgradeInfo(Object obj) {
|
||||
Validate.notNull(obj, "Argument must not be null");
|
||||
/**
|
||||
* Generate a <code>DoubleUpgradeInfo</code> from this <code><b>String</b></code>
|
||||
* that represents a {@link PlusMinusPercent}.
|
||||
* <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 {
|
||||
|
||||
// Shall not be null
|
||||
Validate.notNull(obj, FriendlyFeedbackProvider.QuickForConsole(FriendlyFeedbackPalette_MMOItems.get(), "Upgrade operation must not be null"));
|
||||
|
||||
// Does the string exist?
|
||||
String str = obj.toString();
|
||||
if (str.isEmpty())
|
||||
throw new IllegalArgumentException("Couldn't read amount");
|
||||
if (str.isEmpty()) {
|
||||
throw new IllegalArgumentException(
|
||||
FriendlyFeedbackProvider.QuickForConsole(FriendlyFeedbackPalette_MMOItems.get(), "Upgrade operation is empty"));
|
||||
}
|
||||
|
||||
relative = str.toCharArray()[str.length() - 1] == '%';
|
||||
amount = relative ? MMOUtils.parseDouble(str.substring(0, str.length() - 1)) / 100 : MMOUtils.parseDouble(str);
|
||||
// Adapt to PMP format
|
||||
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(FriendlyFeedbackPalette_MMOItems.get());
|
||||
PlusMinusPercent pmpRead = PlusMinusPercent.getFromString(str, ffp);
|
||||
if (pmpRead == null) {
|
||||
throw new IllegalArgumentException(
|
||||
ffp.getFeedbackOf(FriendlyFeedbackCategory.ERROR).get(0).forConsole(ffp.getPalette()));
|
||||
}
|
||||
|
||||
// Success
|
||||
return new DoubleUpgradeInfo(pmpRead);
|
||||
}
|
||||
|
||||
public double getAmount() {
|
||||
return amount;
|
||||
}
|
||||
public DoubleUpgradeInfo(@NotNull PlusMinusPercent pmp) { this.pmp = pmp; }
|
||||
|
||||
public boolean isRelative() {
|
||||
return relative;
|
||||
}
|
||||
/**
|
||||
* The operation every level will perform.
|
||||
* @see PlusMinusPercent
|
||||
*/
|
||||
@NotNull public PlusMinusPercent getPMP() { return pmp; }
|
||||
}
|
||||
}
|
||||
|
@ -2,13 +2,15 @@ package net.Indyuce.mmoitems.stat.type;
|
||||
|
||||
import com.google.gson.*;
|
||||
import io.lumine.mythic.lib.api.item.ItemTag;
|
||||
import net.Indyuce.mmoitems.ItemStats;
|
||||
import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackCategory;
|
||||
import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackProvider;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.api.UpgradeTemplate;
|
||||
import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem;
|
||||
import net.Indyuce.mmoitems.api.util.message.FriendlyFeedbackPalette_MMOItems;
|
||||
import net.Indyuce.mmoitems.stat.data.*;
|
||||
import net.Indyuce.mmoitems.stat.data.type.Mergeable;
|
||||
import net.Indyuce.mmoitems.stat.data.type.StatData;
|
||||
import net.Indyuce.mmoitems.stat.data.type.UpgradeInfo;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@ -23,6 +25,7 @@ import java.util.*;
|
||||
* <p></p>
|
||||
* This class will store the different sources of each stat UPON being modified.
|
||||
*/
|
||||
@SuppressWarnings({"unused", "unchecked", "SpellCheckingInspection"})
|
||||
public class StatHistory<S extends StatData> {
|
||||
|
||||
/*
|
||||
@ -122,9 +125,9 @@ public class StatHistory<S extends StatData> {
|
||||
|
||||
// Found? Thats it
|
||||
if (hist != null) {
|
||||
//GEM//MMOItems.Log("Found Stat History of \u00a76" + ofStat.getNBTPath() + "\u00a77 in this \u00a7c" + ofItem.getType().getName() + " " + ofItem.getId());
|
||||
//GEM////UPGRD//MMOItems. Log("Found Stat History of \u00a76" + ofStat.getNBTPath() + "\u00a77 in this \u00a7c" + ofItem.getType().getName() + " " + ofItem.getId());
|
||||
return hist; }
|
||||
//GEM//MMOItems.Log("\u00a7aCreated Hisotry of \u00a76" + ofStat.getNBTPath() + "\u00a7a of this \u00a7c" + ofItem.getType().getName() + " " + ofItem.getId());
|
||||
//GEM////UPGRD//MMOItems. Log("\u00a7aCreated Hisotry of \u00a76" + ofStat.getNBTPath() + "\u00a7a of this \u00a7c" + ofItem.getType().getName() + " " + ofItem.getId());
|
||||
|
||||
// That is Mergeable right...
|
||||
Validate.isTrue(ofStat.getClearStatData() instanceof Mergeable, "Non-Mergeable stat data wont have a Stat History; they cannot be modified dynamically in the first place.");
|
||||
@ -133,11 +136,11 @@ public class StatHistory<S extends StatData> {
|
||||
StatData original = ofItem.getData(ofStat);
|
||||
if (original == null) {
|
||||
original = ofStat.getClearStatData();
|
||||
//GEM// MMOItems.Log("\u00a7e +\u00a77 Item didnt have this stat, original set as blanc.");
|
||||
//GEM// //UPGRD//MMOItems. Log("\u00a7e +\u00a77 Item didnt have this stat, original set as blanc.");
|
||||
}
|
||||
else {
|
||||
original = ((Mergeable) original).cloneData();
|
||||
//GEM//MMOItems.Log("\u00a7a +\u00a77 Found original data");
|
||||
//GEM////UPGRD//MMOItems. Log("\u00a7a +\u00a77 Found original data");
|
||||
}
|
||||
|
||||
// Create new
|
||||
@ -159,12 +162,33 @@ public class StatHistory<S extends StatData> {
|
||||
|
||||
/**
|
||||
* This recalculates final value of the stats of the item.
|
||||
* <p></p>
|
||||
* This will not apply the changes, it will just give you the final
|
||||
* <code>StatData</code> that shall be applied (used when upgrading).
|
||||
*/
|
||||
@NotNull public S Recalculate() {
|
||||
|
||||
// Double Data shall account for upgrade levels.
|
||||
if (originalData instanceof DoubleData) { return Recalculate_AsDoubleData(); }
|
||||
// If its upgradeable and not level ZERO, it must apply upgrades
|
||||
if ((getMMOItem().getUpgradeLevel() != 0) &&
|
||||
(getItemStat() instanceof Upgradable) &&
|
||||
(getMMOItem().hasUpgradeTemplate())) {
|
||||
|
||||
|
||||
// Recalculate upgrading
|
||||
return Recalculate_AsUpgradeable();
|
||||
}
|
||||
|
||||
// Merge Normally
|
||||
return Recalculate_ThroughClone();
|
||||
}
|
||||
/**
|
||||
* This recalculates values accounting only for gemstones and external data.
|
||||
* <p></p>
|
||||
* In case someone was wondered the contribution of upgrading the item.
|
||||
*/
|
||||
@NotNull public S Recalculate_Unupgraded() {
|
||||
|
||||
// Merge Normally
|
||||
return Recalculate_ThroughClone();
|
||||
}
|
||||
|
||||
@ -178,30 +202,74 @@ public class StatHistory<S extends StatData> {
|
||||
* </p>4: Sums Gem Stone Data (which should be scaled accordingly [Upgrades are entirely merged into their data])
|
||||
* <p>5: Sums external data (modifiers that are not linked to an ID, I suppose by external plugins).
|
||||
*/
|
||||
S Recalculate_AsDoubleData() {
|
||||
private S Recalculate_AsUpgradeable() {
|
||||
//UPGRD//MMOItems. Log("\u00a76|||\u00a77 Calculating as Upgradeable");
|
||||
|
||||
// Start out with original value?
|
||||
double recalculated = ((DoubleData) getOriginalData()).getValue();
|
||||
// Get Upgrade Info?
|
||||
UpgradeInfo inf = getMMOItem().getUpgradeTemplate().getUpgradeInfo(getItemStat());
|
||||
|
||||
// Process Upgrades
|
||||
UpgradeData data = (UpgradeData) getMMOItem().getData(ItemStats.UPGRADE);
|
||||
if (data != null) {
|
||||
// No Upgrade Information? Looks like you're calculating as a normal merge stat
|
||||
if (inf == null) { return Recalculate_ThroughClone(); }
|
||||
|
||||
// Apply scaling
|
||||
UpgradeTemplate template = data.getTemplate();
|
||||
}
|
||||
// Clone original
|
||||
StatData ogCloned = ((Mergeable) originalData).cloneData();
|
||||
|
||||
// Alr time to merge all
|
||||
DoubleData ret = new DoubleData(recalculated);
|
||||
// Level up
|
||||
int lvl = getMMOItem().getUpgradeLevel();
|
||||
//UPGRD//MMOItems. Log("\u00a76 ||\u00a77 Item Level: \u00a7e" + lvl);
|
||||
//UPGRD//MMOItems. Log("\u00a76 >\u00a77 Original Base: \u00a7e" + ((DoubleData) ogCloned).getValue());
|
||||
S ret = (S) ((Upgradable) getItemStat()).apply(ogCloned, inf, lvl);
|
||||
//UPGRD//MMOItems. Log("\u00a76 >\u00a77 Leveled Base: \u00a7e" + ((DoubleData) ret).getValue());
|
||||
|
||||
// Add up gemstones
|
||||
for (S d : perGemstoneData.values()) { ret.merge(d); }
|
||||
for (UUID d : perGemstoneData.keySet()) {
|
||||
|
||||
// Identify insertion level (When was the gemstone put into the item?
|
||||
int level = 0;
|
||||
|
||||
// Whats this gemstone's upgrade level?
|
||||
for (GemstoneData gData : getMMOItem().getGemStones()) {
|
||||
|
||||
// Find that one of matching UUID
|
||||
if (gData.getHistoricUUID().equals(d)) {
|
||||
|
||||
if (gData.isScaling()) {
|
||||
|
||||
// Ok
|
||||
level = gData.getLevel();
|
||||
|
||||
} else {
|
||||
|
||||
// No scaling
|
||||
level = lvl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate level difference
|
||||
int gLevel = lvl - level;
|
||||
//UPGRD//MMOItems. Log("\u00a76 |\u00a7b|\u00a76>\u00a77 Gemstone Level: \u00a7e" + gLevel + "\u00a77 (Put at \u00a7b" + level + "\u00a77)");
|
||||
|
||||
//UPGRD//MMOItems. Log("\u00a76 \u00a7b|>\u00a77 Gemstone Base: \u00a7e" + ((DoubleData) getGemstoneData(d)).getValue());
|
||||
// Apply upgrades
|
||||
StatData gRet = ((Upgradable) getItemStat()).apply(((Mergeable) getGemstoneData(d)).cloneData(), inf, gLevel);
|
||||
//UPGRD//MMOItems. Log("\u00a76 \u00a7b|>\u00a77 Leveled Base: \u00a7e" + ((DoubleData) gRet).getValue());
|
||||
|
||||
// Merge
|
||||
((Mergeable) ret).merge(gRet);
|
||||
}
|
||||
|
||||
// Add up externals
|
||||
for (S d : perExternalData) { ret.merge(d); }
|
||||
for (S d : perExternalData) {
|
||||
|
||||
//UPGRD//MMOItems. Log("\u00a76 >\u00a7c> \u00a77 Extraneous Base: \u00a7e" + ((DoubleData) d).getValue());
|
||||
// Just merge ig
|
||||
((Mergeable) ret).merge(((Mergeable) d).cloneData());
|
||||
}
|
||||
|
||||
// Return result
|
||||
return (S) ret;
|
||||
//UPGRD//MMOItems. Log("\u00a76:::\u00a77 Result: \u00a7e" + ((DoubleData) ret).getValue());
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -213,19 +281,28 @@ public class StatHistory<S extends StatData> {
|
||||
* </p>3: Sums Gem Stone Data (which should be scaled accordingly [Upgrades are entirely merged into their data])
|
||||
* <p>4: Sums external data (modifiers that are not linked to an ID, I suppose by external plugins).
|
||||
*/
|
||||
S Recalculate_ThroughClone() {
|
||||
private S Recalculate_ThroughClone() {
|
||||
//UPGRD//MMOItems. Log("\u00a73|||\u00a77 Calculating as Clonium");
|
||||
|
||||
// Just clone bro
|
||||
S ret = (S) ((Mergeable) getOriginalData()).cloneData();
|
||||
//UPGRD//MMOItems. Log("\u00a73 > \u00a77 Original Base: \u00a7e" + ((DoubleData) ret).getValue());
|
||||
|
||||
// Add up gemstones
|
||||
for (S d : perGemstoneData.values()) { ((Mergeable) ret).merge(d); }
|
||||
for (S d : perGemstoneData.values()) {
|
||||
//UPGRD//MMOItems. Log("\u00a73 >\u00a7b> \u00a77 Gemstone Base: \u00a7e" + ((DoubleData) d).getValue());
|
||||
((Mergeable) ret).merge(d);
|
||||
}
|
||||
|
||||
// Add up externals
|
||||
for (S d : perExternalData) { ((Mergeable) ret).merge(d); }
|
||||
for (S d : perExternalData) {
|
||||
//UPGRD//MMOItems. Log("\u00a73 >\u00a7c> \u00a77 Extraneous Base: \u00a7e" + ((DoubleData) d).getValue());
|
||||
((Mergeable) ret).merge(d);
|
||||
}
|
||||
|
||||
// Return result
|
||||
return (S) ret;
|
||||
//UPGRD//MMOItems. Log("\u00a73:::\u00a77 Result: \u00a7b" + ((DoubleData) ret).getValue());
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -442,9 +519,11 @@ public class StatHistory<S extends StatData> {
|
||||
|
||||
} catch (Throwable e) {
|
||||
|
||||
// Annoying
|
||||
MMOItems.SLog("Error produced when getting stat history: \u00a7c" + e.getMessage() + "\u00a77 at \u00a76 " + e.getStackTrace()[0]);
|
||||
|
||||
// Feedbacc
|
||||
FriendlyFeedbackProvider ffp = new FriendlyFeedbackProvider(FriendlyFeedbackPalette_MMOItems.get());
|
||||
ffp.ActivatePrefix(true, "Stat History");
|
||||
ffp.Log(FriendlyFeedbackCategory.ERROR, "Could not get stat history: $f{0}$b at $f{1}", e.getMessage(), e.getStackTrace()[0].toString());
|
||||
ffp.SendTo(FriendlyFeedbackCategory.ERROR, MMOItems.getConsole());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,16 @@
|
||||
package net.Indyuce.mmoitems.stat.type;
|
||||
|
||||
import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem;
|
||||
import net.Indyuce.mmoitems.stat.data.type.Mergeable;
|
||||
import net.Indyuce.mmoitems.stat.data.type.StatData;
|
||||
import net.Indyuce.mmoitems.stat.data.type.UpgradeInfo;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* The methods required for this ItemStat to be Upgradeable. <p></p>
|
||||
* <b>It makes sense then that the <code>StatData</code> this uses
|
||||
* implements {@link Mergeable}</b> and it is even assumed so.
|
||||
*/
|
||||
public interface Upgradable {
|
||||
|
||||
/*
|
||||
@ -11,12 +19,32 @@ public interface Upgradable {
|
||||
* increase when upgrading the item!
|
||||
*/
|
||||
|
||||
/*
|
||||
* argument 'obj' is either a primitive object like string, boolean or
|
||||
* double or a configuration section. the method must check if this argument
|
||||
* is of the right type. this method ONLY handles IllegalArgumentExceptions
|
||||
/**
|
||||
* When an {@link net.Indyuce.mmoitems.api.UpgradeTemplate} is read from a YML file,
|
||||
* it loads each stat's {@link UpgradeInfo} through this method, passing on the
|
||||
* object mapped to the stat in the configuration.
|
||||
* <p></p>
|
||||
* For example:
|
||||
* <p><code>attack-damage: <b>10%</b></code>
|
||||
* </p>Passes that <code><b>10%</b></code> as an object (not even as a string yet)
|
||||
* <p></p>
|
||||
* This method ONLY handles <code>IllegalArgumentException</code>s which
|
||||
* you are free to throw.
|
||||
* @param obj Is the thing itself written onto the YML file.
|
||||
* <p></p>
|
||||
* It is up to you to know what this is, most universally
|
||||
* a string that you can get with <code>obj.toString()</code>.
|
||||
* <p></p>
|
||||
* If your stat is more complicated than just a number, it
|
||||
* may be a {@link org.bukkit.configuration.ConfigurationSection}, who knows?
|
||||
* @throws IllegalArgumentException If something (anything) goes wrong.
|
||||
*/
|
||||
UpgradeInfo loadUpgradeInfo(Object obj);
|
||||
@NotNull UpgradeInfo loadUpgradeInfo(@Nullable Object obj) throws IllegalArgumentException;
|
||||
|
||||
void apply(MMOItem mmoitem, UpgradeInfo info);
|
||||
/**
|
||||
* Applies this upgrade info <b>level</b> times to this stat data.
|
||||
* @param level The level of the returned StatData, how many times the Upgrade Info will be applied.
|
||||
* May be negative if the stat supports it.
|
||||
*/
|
||||
@NotNull StatData apply(@NotNull StatData original, @NotNull UpgradeInfo info, int level);
|
||||
}
|
||||
|
@ -86,7 +86,9 @@ item-upgrading:
|
||||
|
||||
# How stat changes are formatted
|
||||
# in the stat suffix.
|
||||
stat-change-suffix: '&f &e(+#stat#)'
|
||||
stat-change-suffix: ' &8(&p#stat#&8)'
|
||||
stat-change-positive: '&a'
|
||||
stat-change-negative: '&c'
|
||||
|
||||
# Whether or not to display which
|
||||
# stats are changed in the lore.
|
||||
|
Loading…
Reference in New Issue
Block a user