From c1ecc198e32d111ee97cea35dd0fdb533ec469f9 Mon Sep 17 00:00:00 2001
From: Jules
Date: Sat, 6 Apr 2024 15:50:19 -0700
Subject: [PATCH] Fixed abilities not transfering from gems
---
.../crafting/recipe/CustomSmithingRecipe.java | 3 +-
.../mmoitems/api/interaction/GemStone.java | 119 +--
.../api/item/build/ItemStackBuilder.java | 2 +-
.../api/item/build/MMOItemBuilder.java | 2 +-
.../mmoitems/api/item/mmoitem/MMOItem.java | 753 +++++++++---------
.../mmoitems/stat/data/AbilityData.java | 8 +
.../mmoitems/stat/data/AbilityListData.java | 11 +-
.../mmoitems/stat/data/GemSocketsData.java | 23 +-
.../mmoitems/stat/data/type/Mergeable.java | 2 +-
.../mmoitems/stat/type/DoubleStat.java | 38 +-
.../mmoitems/stat/type/StatHistory.java | 541 +++----------
11 files changed, 568 insertions(+), 934 deletions(-)
diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/crafting/recipe/CustomSmithingRecipe.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/crafting/recipe/CustomSmithingRecipe.java
index 321167fb..c5fc2d23 100644
--- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/crafting/recipe/CustomSmithingRecipe.java
+++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/crafting/recipe/CustomSmithingRecipe.java
@@ -18,6 +18,7 @@ import net.Indyuce.mmoitems.api.interaction.GemStone;
import net.Indyuce.mmoitems.api.item.mmoitem.LiveMMOItem;
import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem;
import net.Indyuce.mmoitems.api.item.template.MMOItemTemplate;
+import net.Indyuce.mmoitems.api.player.PlayerData;
import net.Indyuce.mmoitems.api.util.message.FFPMMOItems;
import net.Indyuce.mmoitems.stat.Enchants;
import net.Indyuce.mmoitems.stat.data.EnchantListData;
@@ -601,7 +602,7 @@ public class CustomSmithingRecipe extends MythicRecipeOutput {
continue; }
// Ok proceed
- GemStone asGem = new GemStone(p, m.newBuilder().buildNBT());
+ GemStone asGem = new GemStone(PlayerData.get(p), m.newBuilder().buildNBT());
// Put
GemStone.ApplyResult res = asGem.applyOntoItem(gen, gen.getType(), "", false, true);
diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/GemStone.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/GemStone.java
index caead8d0..02f06757 100644
--- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/GemStone.java
+++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/GemStone.java
@@ -45,8 +45,7 @@ public class GemStone extends UseItem {
* Entirely loads the MMOItem and checks if
* it has the required empty socket for the gem
*/
- MMOItem targetMMO = new LiveMMOItem(target);
- return applyOntoItem(targetMMO, targetType, MMOUtils.getDisplayName(target.getItem()), true, false);
+ return applyOntoItem(new LiveMMOItem(target), targetType, MMOUtils.getDisplayName(target.getItem()), true, false);
}
@NotNull
@@ -64,7 +63,7 @@ public class GemStone extends UseItem {
// Checks if the gem supports the item type, or the item set, or a weapon
String appliableTypes = getNBTItem().getString(ItemStats.ITEM_TYPE_RESTRICTION.getNBTPath());
- if (!appliableTypes.equals("") && (!targetType.isWeapon() || !appliableTypes.contains("WEAPON"))
+ if (!appliableTypes.isEmpty() && (!targetType.isWeapon() || !appliableTypes.contains("WEAPON"))
&& !appliableTypes.contains(targetType.getId()))
return new ApplyResult(ResultType.NONE);
@@ -89,79 +88,29 @@ public class GemStone extends UseItem {
return new ApplyResult(ResultType.FAILURE);
}
- /*
- * To not clear enchantments put by players
- */
+ // To not clear enchantments put by players
Enchants.separateEnchantments(targetMMO);
/*
- * Gem stone can be successfully applied. apply stats then abilities and
- * permanent effects. also REGISTER gem stone in the item gem stone list.
+ * Gemstone can be successfully applied. Apply stats then abilities and
+ * permanent effects. also REGISTER gemstone in the item gemstone list.
*/
LiveMMOItem gemMMOItem = new LiveMMOItem(getNBTItem());
GemstoneData gemData = new GemstoneData(gemMMOItem, foundSocketColor);
/*
* Now must apply the gem sockets data to the Stat History and then recalculate.
- *
- * Gotta, however, find the correct StatData to which apply it to. Damn this can
- * be pretty complicated!
+ * Gotta, however, find the correct StatData to which apply it to.
*/
StatHistory gemStory = StatHistory.from(targetMMO, ItemStats.GEM_SOCKETS);
-
- // Original?
- if (((GemSocketsData) gemStory.getOriginalData()).getEmptySocket(gemType) != null) {
- //UPGRD//MMOItems.log("\u00a77Applied Gemstone @\u00a76Original\u00a77: \u00a73" + foundSocketColor);
-
- // Charmer
- ((GemSocketsData) gemStory.getOriginalData()).apply(gemType, gemData);
-
- } else {
-
- // Check Gem gems are not supported >:l. Check the modifiers ig
- boolean success = false;
- for (UUID uid : gemStory.getAllModifiers()) {
-
- // Get that gem
- GemSocketsData registeredGemData = (GemSocketsData) gemStory.getModifiersBonus(uid);
- if (registeredGemData != null && registeredGemData.getEmptySocket(gemType) != null) {
- //UPGRD//MMOItems.log("\u00a77Applied Gemstone @\u00a76Gemstone\u00a77: \u00a73" + foundSocketColor);
-
- // Charmer
- success = true;
- registeredGemData.apply(gemType, gemData);
- break;
- }
- }
-
- if (!success) {
-
- for (StatData extraneousGem : gemStory.getExternalData()) {
-
- // Get that gem
- GemSocketsData registeredGemData = (GemSocketsData) extraneousGem;
- if (registeredGemData != null && registeredGemData.getEmptySocket(gemType) != null) {
- //UPGRD//MMOItems.log("\u00a77Applied Gemstone @\u00a76External\u00a77: \u00a73" + foundSocketColor);
-
- // Charmer
- registeredGemData.apply(gemType, gemData);
- break;
- }
- }
- }
- }
-
- // Recalculate
- //HSY//MMOItems.log(" \u00a73-\u00a7a- \u00a77Gem Application Recalculation \u00a73-\u00a7a-\u00a73-\u00a7a-\u00a73-\u00a7a-\u00a73-\u00a7a-");
+ findEmptySocket(gemStory, gemType, gemData);
targetMMO.setData(ItemStats.GEM_SOCKETS, gemStory.recalculate(targetMMO.getUpgradeLevel()));
- //UPGRD//MMOItems.log("Applied Gemstone: \u00a73" + foundSocketColor);
/*
* Get the item's level, important for the GemScalingStat
*/
Integer levelIdentified = null;
final String scaling = gemMMOItem.hasData(ItemStats.GEM_UPGRADE_SCALING) ? gemMMOItem.getData(ItemStats.GEM_UPGRADE_SCALING).toString() : GemUpgradeScaling.defaultValue;
- //UPGRD//MMOItems.log("Scaling Identified: \u00a73" + scaling);
switch (scaling) {
case "HISTORIC":
levelIdentified = 0;
@@ -169,32 +118,18 @@ public class GemStone extends UseItem {
case "SUBSEQUENT":
levelIdentified = targetMMO.getUpgradeLevel();
break;
- case "NEVER":
default:
break;
}
-
gemData.setLevel(levelIdentified);
- //UPGRD//MMOItems.log("Set Level: \u00a7b" + gemData.getLevel());
- /*
- * Only applies NON PROPER and MERGEABLE item stats
- */
+
+ // Only applies NON PROPER and MERGEABLE item stats
for (ItemStat stat : gemMMOItem.getStats()) {
+ if (stat instanceof GemStoneStat) continue;
- // If it is not PROPER
- if (!(stat instanceof GemStoneStat)) {
-
- // Get the stat data
- StatData data = gemMMOItem.getData(stat);
-
- // If the data is MERGEABLE
- if (data instanceof Mergeable) {
- //UPGRD//MMOItems.log("\u00a79>>> \u00a77Gem-Merging \u00a7c" + stat.getNBTPath());
-
- // Merge into it
- targetMMO.mergeData(stat, data, gemData.getHistoricUUID());
- }
- }
+ final StatData data = gemMMOItem.getData(stat);
+ if (data instanceof Mergeable)
+ targetMMO.mergeData(stat, data, gemData.getHistoricUUID());
}
if (!silent) {
@@ -204,11 +139,37 @@ public class GemStone extends UseItem {
if (buildStack)
return new ApplyResult(targetMMO.newBuilder().build());
-
else
return new ApplyResult(targetMMO, ResultType.SUCCESS);
}
+ private void findEmptySocket(StatHistory socketHistory, String gemType, GemstoneData gemstone) {
+
+ // Og data
+ GemSocketsData data = ((GemSocketsData) socketHistory.getOriginalData());
+ if (data.apply(gemType, gemstone)) return;
+
+ // Modifiers
+ for (UUID modifierId : socketHistory.getAllModifiers()) {
+ data = (GemSocketsData) socketHistory.getModifiersBonus(modifierId);
+ if (data.apply(gemType, gemstone)) return;
+ }
+
+ // External
+ for (StatData untypedData : socketHistory.getExternalData()) {
+ data = (GemSocketsData) untypedData;
+ if (data.apply(gemType, gemstone)) return;
+ }
+
+ // Gems
+ for (UUID gemId : socketHistory.getAllGemstones()) {
+ data = (GemSocketsData) socketHistory.getGemstoneData(gemId);
+ if (data.apply(gemType, gemstone)) return;
+ }
+
+ throw new RuntimeException("MMOItem contains available socket but not its socket stat history");
+ }
+
public static class ApplyResult {
@NotNull
private final ResultType type;
diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/item/build/ItemStackBuilder.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/item/build/ItemStackBuilder.java
index 980d09ab..84e4afb2 100644
--- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/item/build/ItemStackBuilder.java
+++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/item/build/ItemStackBuilder.java
@@ -168,7 +168,7 @@ public class ItemStackBuilder {
builtMMOItem.setData(stat, s.recalculate(l));
// Add to NBT, if the gemstones were not purged
- if (!s.isClear()) {
+ if (!s.isEmpty()) {
//GEM//MMOItems.log("\u00a7a -+- \u00a77Recording History");
addItemTag(new ItemTag(history_keyword + stat.getId(), s.toNBTString()));
diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/item/build/MMOItemBuilder.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/item/build/MMOItemBuilder.java
index 50a49310..65ea2bf9 100644
--- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/item/build/MMOItemBuilder.java
+++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/item/build/MMOItemBuilder.java
@@ -145,7 +145,7 @@ public class MMOItemBuilder extends Buildable {
*/
public void applyData(@NotNull ItemStat stat, @NotNull StatData data) {
final StatData found = mmoitem.getData(stat);
- if (found != null && found instanceof Mergeable) ((Mergeable) found).mergeWith(data);
+ if (found != null && found instanceof Mergeable) ((Mergeable) found).mergeWith((Mergeable) data);
else mmoitem.setData(stat, data);
}
diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/item/mmoitem/MMOItem.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/item/mmoitem/MMOItem.java
index bc78c78c..6a7c3f06 100644
--- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/item/mmoitem/MMOItem.java
+++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/item/mmoitem/MMOItem.java
@@ -27,204 +27,188 @@ import java.util.*;
@SuppressWarnings("unused")
public class MMOItem implements ItemReference {
- private final Type type;
- private final String id;
+ private final Type type;
+ private final String id;
- /**
- * Where data about all the item stats is stored. When the item is
- * generated, this map is read and all the stats are applied. The order in
- * which stats are added is not very important anymore
- */
- @NotNull
- private final Map stats = new HashMap<>();
+ /**
+ * Where data about all the item stats is stored. When the item is
+ * generated, this map is read and all the stats are applied. The order in
+ * which stats are added is not very important anymore
+ */
+ @NotNull
+ private final Map stats = new HashMap<>();
- /**
- * Constructor used to generate an ItemStack based on some stat data
- *
- * @param type
- * The type of the item you want to create
- * @param id
- * The id of the item, make sure it is different from other
- * existing items not to interfere with MI features like the
- * dynamic item updater
- */
- public MMOItem(Type type, String id) {
- this.type = type;
- this.id = id;
- }
+ /**
+ * Constructor used to generate an ItemStack based on some stat data
+ *
+ * @param type The type of the item you want to create
+ * @param id The id of the item, make sure it is different from other
+ * existing items not to interfere with MI features like the
+ * dynamic item updater
+ */
+ public MMOItem(Type type, String id) {
+ this.type = type;
+ this.id = id;
+ }
- @Override
- public Type getType() { return type; }
+ @Override
+ public Type getType() {
+ return type;
+ }
- @Override
- public String getId() { return id; }
+ @Override
+ public String getId() {
+ return id;
+ }
- /**
- * Will merge that data into this item:
- *
- * If the item does not have this stat yet, it will be set with MMOItem.setData()
- * If this data is not Mergeable
, it will also be set
- *
- * Otherwise, the data will be merged with the previous. If an UUID is provided, it will also be
- * stored as a GemStone in the history, allowing to be removed from the item with that same UUID.
- */
- public void mergeData(@NotNull ItemStat stat, @NotNull StatData data, @Nullable UUID associatedGemStone) {
- //GEM//MMOItems.log("Merging stone stat \u00a76" + stat.getNBTPath() + "\u00a77 into \u00a7c" + getType().getName() + " " + getId());
+ /**
+ * Will merge that data into this item:
+ *
+ * If the item does not have this stat yet, it will be set with MMOItem.setData()
+ * If this data is not Mergeable
, it will also be set
+ *
+ * Otherwise, the data will be merged with the previous. If an UUID is provided, it will also be
+ * stored as a GemStone in the history, allowing to be removed from the item with that same UUID.
+ */
+ public void mergeData(@NotNull ItemStat stat, @NotNull StatData data, @Nullable UUID associatedGemStone) {
+ boolean bc = stat.equals(ItemStats.ABILITIES);
- // Do we already have the data?
- if (data instanceof Mergeable) {
- //GEM//MMOItems.log("\u00a7a + \u00a77Mergeable");
+ // Merge if possible, otherwise write over
+ if (data instanceof Mergeable) {
- // Prepare to merge: Gather History (Also initializes the ORIGINAL stats)
- StatHistory sHistory = StatHistory.from(this, stat);
+ // Prepare to merge, gather history
+ StatHistory sHistory = StatHistory.from(this, stat);
+ if (associatedGemStone != null) sHistory.registerGemstoneData(associatedGemStone, data);
+ else sHistory.registerExternalData(data);
+ setData(stat, sHistory.recalculate(getUpgradeLevel()));
+ } else
+ setData(stat, data);
+ }
- // As GemStone or as External?
- if (associatedGemStone != null) {
- //GEM//MMOItems.log(" \u00a79++\u00a77 As Gemstone \u00a7b" + associatedGemStone.toString());
+ public void setData(@NotNull ItemStat stat, @NotNull StatData data) {
+ stats.put(stat, data);
+ }
- // As GemStone
- sHistory.registerGemstoneData(associatedGemStone, data);
+ public void replaceData(@NotNull ItemStat stat, @NotNull StatData data) {
+ stats.replace(stat, data);
+ }
- // As External
- } else {
- //GEM//MMOItems.log(" \u00a7c++\u00a77 As External");
+ public void removeData(@NotNull ItemStat stat) {
+ stats.remove(stat);
+ }
- // As External, UUIDless modifier
- sHistory.registerExternalData(data);
- }
+ public StatData getData(@NotNull ItemStat stat) {
+ return stats.get(stat);
+ }
- // Recalculate
- //GEM//MMOItems.log(" \u00a76+++\u00a77 Recalculating...");
- //HSY//MMOItems.log(" \u00a73-\u00a7a- \u00a77Gem Application Recalculation \u00a73-\u00a7a-\u00a73-\u00a7a-\u00a73-\u00a7a-\u00a73-\u00a7a-");
- setData(stat, sHistory.recalculate(getUpgradeLevel()));
+ public boolean hasData(@NotNull ItemStat stat) {
+ return (stats.get(stat) != null);
+ }
- // Merging means replacing if it cannot be merged
- } else {
+ /**
+ * @return Collection of all item stats which have some data on this mmoitem
+ */
+ @NotNull
+ public Set getStats() {
+ return stats.keySet();
+ }
+ //endregion
- // Override Completely
- setData(stat, data);
- }
- }
+ //region Building
- public void setData(@NotNull ItemStat stat, @NotNull StatData data) {
- stats.put(stat, data);
- }
+ /**
+ * @return A class which lets you build this mmoitem into an ItemStack
+ */
+ @NotNull
+ public ItemStackBuilder newBuilder() {
+ return new ItemStackBuilder(this);
+ }
- public void replaceData(@NotNull ItemStat stat, @NotNull StatData data) {
- stats.replace(stat, data);
- }
+ /***
+ * @return A cloned instance of this mmoitem. This does NOT clone the
+ * StatData instances! If you edit these statDatas, the previous
+ * mmoitem will be edited as well.
+ */
+ @SuppressWarnings("MethodDoesntCallSuperMethod")
+ @Override
+ public MMOItem clone() {
+ MMOItem clone = new MMOItem(type, id);
- public void removeData(@NotNull ItemStat stat) {
- stats.remove(stat);
- }
+ // Clone them stats and histories
+ for (ItemStat stat : stats.keySet()) {
- public StatData getData(@NotNull ItemStat stat) {
- return stats.get(stat);
- }
+ // Copy Stat Datas themselves
+ clone.stats.put(stat, stats.get(stat));
- public boolean hasData(@NotNull ItemStat stat) { return (stats.get(stat) != null); }
+ // Copy Histories
+ StatHistory hist = getStatHistory(stat);
+ if (hist != null) {
+ final StatHistory histClone = hist.clone();
+ histClone.setParent(clone);
+ clone.setStatHistory(stat, histClone);
+ }
+ }
- /**
- * @return Collection of all item stats which have some data on this mmoitem
- */
- @NotNull public Set getStats() {
- return stats.keySet();
- }
- //endregion
+ // Thats it
+ return clone;
+ }
+ //endregion
- //region Building and such
- /**
- * @return A class which lets you build this mmoitem into an ItemStack
- */
- @NotNull public ItemStackBuilder newBuilder() {
- return new ItemStackBuilder(this);
- }
+ //region Stat History Stuff
+ /*
+ * When merging stats (like applying a gemstone), the item must remember which were
+ * its original stats, and from which gem stone came each stat, in order to allow
+ * removal of gem stones in the future. This is where that is remembered.
+ */
+ @NotNull
+ private final Map mergeableStatHistory = new HashMap<>();
- /***
- * @return A cloned instance of this mmoitem. This does NOT clone the
- * StatData instances! If you edit these statDatas, the previous
- * mmoitem will be edited as well.
- */
- @SuppressWarnings("MethodDoesntCallSuperMethod")
- @Override
- public MMOItem clone() {
- MMOItem clone = new MMOItem(type, id);
+ /**
+ * Gets the history associated to this stat, if there is any
+ *
+ * A stat history is basically the memory of its original stats,
+ * from when it was created, its gemstone stats,
+ * those added by which gem, and its upgrade bonuses.
+ */
+ @Nullable
+ public StatHistory getStatHistory(@NotNull ItemStat stat) {
- // Clone them stats and histories
- for (ItemStat stat : stats.keySet()) {
+ /*
+ * As an assumption for several enchantment recognition operations,
+ * Enchantment data must never be clear and lack history. This is
+ * the basis for when an item is 'old'
+ */
+ if (stat instanceof Enchants)
+ return mergeableStatHistory.getOrDefault(stat, StatHistory.from(this, stat, true));
- // Copy Stat Datas themselves
- clone.stats.put(stat, stats.get(stat));
+ /*
+ * Normal stat, just fetch.
+ */
+ try {
- // Copy Histories
- StatHistory hist = getStatHistory(stat);
- if (hist != null) {
- final StatHistory histClone = hist.clone();
- histClone.setParent(clone);
- clone.setStatHistory(stat, histClone);
- }
- }
+ // Well that REALLY should work
+ return mergeableStatHistory.get(stat);
- // Thats it
- return clone;
- }
- //endregion
+ } catch (ClassCastException ignored) {
+ return null;
+ }
+ }
- //region Stat History Stuff
- /*
- * When merging stats (like applying a gemstone), the item must remember which were
- * its original stats, and from which gem stone came each stat, in order to allow
- * removal of gem stones in the future. This is where that is remembered.
- */
- @NotNull
- private final Map mergeableStatHistory = new HashMap<>();
+ @NotNull
+ public ArrayList getStatHistories() {
+ return new ArrayList<>(mergeableStatHistory.values());
+ }
- /**
- * Gets the history associated to this stat, if there is any
- *
- * A stat history is basically the memmory of its original stats,
- * from when it was created, its gem stone stats,
- * those added by which gem, and its upgrade bonuses.
- */
- @Nullable
- public StatHistory getStatHistory(@NotNull ItemStat stat) {
-
- /*
- * As an assumption for several enchantment recognition operations,
- * Enchantment data must never be clear and lack history. This is
- * the basis for when an item is 'old'
- */
- if (stat instanceof Enchants)
- return mergeableStatHistory.getOrDefault(stat, StatHistory.from(this, stat, true));
-
- /*
- * Normal stat, just fetch.
- */
- try {
-
- // Well that REALLY should work
- return mergeableStatHistory.get(stat);
-
- } catch (ClassCastException ignored) {
- return null;
- }
- }
-
- @NotNull
- public ArrayList getStatHistories() {
- return new ArrayList<>(mergeableStatHistory.values());
- }
-
- /**
- * Sets the history associated to this stat.
- *
- * A stat history is basically the memory of its original stats,
- * from when it was created, its gemstone stats, those
- * added by which gem, and its upgrade bonuses.
- */
- public void setStatHistory(@NotNull ItemStat stat, @NotNull StatHistory hist) {
- mergeableStatHistory.put(stat, hist);
- }
+ /**
+ * Sets the history associated to this stat.
+ *
+ * A stat history is basically the memory of its original stats,
+ * from when it was created, its gemstone stats, those
+ * added by which gem, and its upgrade bonuses.
+ */
+ public void setStatHistory(@NotNull ItemStat stat, @NotNull StatHistory hist) {
+ mergeableStatHistory.put(stat, hist);
+ }
//region Other API
@@ -246,272 +230,265 @@ public class MMOItem implements ItemReference {
return found != null ? MMOItems.plugin.getLore().getTooltip(found.toString()) : null;
}
- /**
- * A MMOItem from the template only has damage
- * from the ITEM_DAMAGE stat
- *
- * @return The damage suffered by this item
- */
- @Deprecated
- public int getDamage() {
+ /**
+ * A MMOItem from the template only has damage
+ * from the ITEM_DAMAGE stat
+ *
+ * @return The damage suffered by this item
+ */
+ @Deprecated
+ public int getDamage() {
- // Does it use MMO Durability?
- int maxDurability = hasData(ItemStats.MAX_DURABILITY) ? SilentNumbers.round(((DoubleData) getData(ItemStats.MAX_DURABILITY)).getValue()) : -1;
+ // Does it use MMO Durability?
+ int maxDurability = hasData(ItemStats.MAX_DURABILITY) ? SilentNumbers.round(((DoubleData) getData(ItemStats.MAX_DURABILITY)).getValue()) : -1;
- if (maxDurability > 0) {
+ if (maxDurability > 0) {
- // Apparently we must do this
- NBTItem nbtItem = newBuilder().buildNBT();
+ // Apparently we must do this
+ NBTItem nbtItem = newBuilder().buildNBT();
- // Durability
- int durability = hasData(ItemStats.CUSTOM_DURABILITY) ? SilentNumbers.round(((DoubleData) getData(ItemStats.CUSTOM_DURABILITY)).getValue()) : maxDurability;
+ // Durability
+ int durability = hasData(ItemStats.CUSTOM_DURABILITY) ? SilentNumbers.round(((DoubleData) getData(ItemStats.CUSTOM_DURABILITY)).getValue()) : maxDurability;
- // Damage is the difference between max and current durability
- return maxDurability - durability;
+ // Damage is the difference between max and current durability
+ return maxDurability - durability;
- } else {
+ } else {
- // Use vanilla durability
- return hasData(ItemStats.ITEM_DAMAGE) ? SilentNumbers.round(((DoubleData) getData(ItemStats.ITEM_DAMAGE)).getValue()) : 0;
- }
- }
+ // Use vanilla durability
+ return hasData(ItemStats.ITEM_DAMAGE) ? SilentNumbers.round(((DoubleData) getData(ItemStats.ITEM_DAMAGE)).getValue()) : 0;
+ }
+ }
- /**
- * A MMOItem from the template only has damage
- * from the ITEM_DAMAGE stat
- *
- * @param damage The damage suffered by this item
- */
- @Deprecated
- public void setDamage(int damage) {
+ /**
+ * A MMOItem from the template only has damage
+ * from the ITEM_DAMAGE stat
+ *
+ * @param damage The damage suffered by this item
+ */
+ @Deprecated
+ public void setDamage(int damage) {
- // Too powerful
- if (hasData(ItemStats.UNBREAKABLE)) { return; }
+ // Too powerful
+ if (hasData(ItemStats.UNBREAKABLE)) return;
- // Does it use MMO Durability?
- int maxDurability = hasData(ItemStats.MAX_DURABILITY) ? SilentNumbers.round(((DoubleData) getData(ItemStats.MAX_DURABILITY)).getValue()) : -1;
+ // Does it use MMO Durability?
+ int maxDurability = hasData(ItemStats.MAX_DURABILITY) ? SilentNumbers.round(((DoubleData) getData(ItemStats.MAX_DURABILITY)).getValue()) : -1;
- if (maxDurability > 0) {
+ if (maxDurability > 0) {
- // Apparently we must do this
- NBTItem nbtItem = newBuilder().buildNBT();
+ // Apparently we must do this
+ NBTItem nbtItem = newBuilder().buildNBT();
- // Durability
- setData(ItemStats.CUSTOM_DURABILITY, new DoubleData(maxDurability - damage));
+ // Durability
+ setData(ItemStats.CUSTOM_DURABILITY, new DoubleData(maxDurability - damage));
- // Scale damage
- Material mat = hasData(ItemStats.MATERIAL) ? ((MaterialData) getData(ItemStats.MATERIAL)).getMaterial() : Material.GOLD_INGOT;
- double multiplier = ((double) damage) * ((double) mat.getMaxDurability()) / ((double) maxDurability);
- if (multiplier == 0) { return; }
+ // Scale damage
+ Material mat = hasData(ItemStats.MATERIAL) ? ((MaterialData) getData(ItemStats.MATERIAL)).getMaterial() : Material.GOLD_INGOT;
+ double multiplier = ((double) damage) * ((double) mat.getMaxDurability()) / ((double) maxDurability);
+ if (multiplier == 0) return;
- // Set to some decent amount of damage
- setData(ItemStats.ITEM_DAMAGE, new DoubleData(multiplier));
+ // Set to some decent amount of damage
+ setData(ItemStats.ITEM_DAMAGE, new DoubleData(multiplier));
- } else {
+ } else {
- // Use vanilla durability
- setData(ItemStats.ITEM_DAMAGE, new DoubleData(damage));
- }
- }
- //endregion
+ // Use vanilla durability
+ setData(ItemStats.ITEM_DAMAGE, new DoubleData(damage));
+ }
+ }
+ //endregion
- //region Upgrading API
+ //region Upgrading API
- /**
- * Upgrades this MMOItem one level.
- *
- * Make sure to check {@link #hasUpgradeTemplate()} before calling.
- */
- public void upgrade() {
+ /**
+ * Upgrades this MMOItem one level.
+ *
+ * Make sure to check {@link #hasUpgradeTemplate()} before calling.
+ */
+ public void upgrade() {
- // Upgrade through the template's API
- getUpgradeTemplate().upgrade(this);
- }
+ // Upgrade through the template's API
+ getUpgradeTemplate().upgrade(this);
+ }
- /**
- * Whether or not this item has all the information
- * required to call
- */
- public boolean hasUpgradeTemplate() {
- return hasData(ItemStats.UPGRADE) && ((UpgradeData) getData(ItemStats.UPGRADE)).getTemplate() != null;
- }
+ /**
+ * Whether or not this item has all the information
+ * required to call
+ */
+ public boolean hasUpgradeTemplate() {
+ return hasData(ItemStats.UPGRADE) && ((UpgradeData) getData(ItemStats.UPGRADE)).getTemplate() != null;
+ }
- /**
- * @return The upgrade level, or 0 if there is none.
- */
- public int getUpgradeLevel() {
- return hasData(ItemStats.UPGRADE) ? ((UpgradeData) getData(ItemStats.UPGRADE)).getLevel() : 0;
- }
+ /**
+ * @return The upgrade level, or 0 if there is none.
+ */
+ public int getUpgradeLevel() {
+ return hasData(ItemStats.UPGRADE) ? ((UpgradeData) getData(ItemStats.UPGRADE)).getLevel() : 0;
+ }
- /**
- * @return The upgrade level, or 0 if there is none.
- */
- public int getMaxUpgradeLevel() {
+ /**
+ * @return The upgrade level, or 0 if there is none.
+ */
+ public int getMaxUpgradeLevel() {
- // Does it have Upgrade Data?
- if (hasData(ItemStats.UPGRADE)) {
+ // Does it have Upgrade Data?
+ if (hasData(ItemStats.UPGRADE)) {
- // Return the registered level.
- return ((UpgradeData) getData(ItemStats.UPGRADE)).getMax();
- }
+ // Return the registered level.
+ return ((UpgradeData) getData(ItemStats.UPGRADE)).getMax();
+ }
- // Nope? Well its level 0 I guess.
- return 0;
- }
+ // Nope? Well its level 0 I guess.
+ return 0;
+ }
- /**
- * Make sure to check {@link #hasUpgradeTemplate()} before calling.
- *
- * 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.
- */
- @SuppressWarnings("ConstantConditions")
- @NotNull public UpgradeTemplate getUpgradeTemplate() {
- Validate.isTrue(hasUpgradeTemplate(), "Item has no upgrade information");
+ /**
+ * Make sure to check {@link #hasUpgradeTemplate()} before calling.
+ *
+ * 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.
+ */
+ @SuppressWarnings("ConstantConditions")
+ @NotNull
+ public UpgradeTemplate getUpgradeTemplate() {
+ Validate.isTrue(hasUpgradeTemplate(), "Item has no upgrade information");
- // All Right
- UpgradeData data = (UpgradeData) getData(ItemStats.UPGRADE);
+ // All Right
+ UpgradeData data = (UpgradeData) getData(ItemStats.UPGRADE);
- // That's the template
- return data.getTemplate();
- }
+ // That's the template
+ return data.getTemplate();
+ }
- /**
- * Get the list of GemStones inserted into this item
- */
- @NotNull
- public Set getGemStones() {
+ @NotNull
+ public List getGemstones() {
+ final StatData data = getData(ItemStats.GEM_SOCKETS);
+ return data == null ? new ArrayList<>() : ((GemSocketsData) data).getGems();
+ }
- // Got gem sockets?
- if (hasData(ItemStats.GEM_SOCKETS)) {
+ /**
+ * @see #getGemstones()
+ */
+ @Deprecated
+ public Set getGemStones() {
+ return new HashSet<>(getGemstones());
+ }
+ //endregion
- // Get Data
- GemSocketsData data = (GemSocketsData) getData(ItemStats.GEM_SOCKETS);
+ //region Gem Sockets API
- // Thats it
- return data.getGemstones();
+ /**
+ * It is not 100% fool-proof, since some GemStones just don't have
+ * enough information to be extracted (legacy gemstones).
+ *
+ * Note that this is somewhat an expensive operation, restrain
+ * from calling it much because it completely loads all the stats
+ * of every Gem Stone.
+ *
+ * @return The list of GemStones contained here.
+ */
+ @NotNull
+ public List> extractGemstones() {
- // Has no gem sockets
- } else {
+ // Found?
+ final @Nullable GemSocketsData thisSocketsData = (GemSocketsData) getData(ItemStats.GEM_SOCKETS);
+ if (thisSocketsData == null)
+ return new ArrayList<>();
- // Empty Set
- return new HashSet<>();
- }
- }
- //endregion
+ // Find restored items
+ final List> pairs = new ArrayList<>();
+ for (GemstoneData gem : thisSocketsData.getGemstones()) {
+ final MMOItem restored = MMOItems.plugin.getMMOItem(MMOItems.plugin.getTypes().get(gem.getMMOItemType()), gem.getMMOItemID());
+ if (restored != null)
+ pairs.add(Pair.of(gem, restored));
+ }
- //region Gem Sockets API
+ // If RevID updating, no need to identify stats
+ if (MMOItemReforger.gemstonesRevIDWhenUnsocket)
+ return pairs;
- /**
- * It is not 100% fool proof, since some GemStones just don't have
- * enough information to be extracted (legacy gemstones).
- *
- * Note that this is somewhat an expensive operation, restrain
- * from calling it much because it completely loads all the stats
- * of every Gem Stone.
- *
- * @return The list of GemStones contained here.
- */
- @NotNull
- public List> extractGemstones() {
+ // Identify actual stats
+ for (StatHistory hist : mergeableStatHistory.values())
+ for (Pair gem : pairs) {
+ final StatData historicGemData = hist.getGemstoneData(gem.getKey().getHistoricUUID());
+ if (historicGemData != null)
+ gem.getValue().setData(hist.getItemStat(), historicGemData);
+ }
- // Found?
- final @Nullable GemSocketsData thisSocketsData = (GemSocketsData) getData(ItemStats.GEM_SOCKETS);
- if (thisSocketsData == null)
- return new ArrayList<>();
+ return pairs;
+ }
- // Find restored items
- final List> pairs = new ArrayList<>();
- for (GemstoneData gem : thisSocketsData.getGemstones()) {
- final MMOItem restored = MMOItems.plugin.getMMOItem(MMOItems.plugin.getTypes().get(gem.getMMOItemType()), gem.getMMOItemID());
- if (restored != null)
- pairs.add(Pair.of(gem, restored));
- }
+ /**
+ * Extracts a single gemstone. Note that this only builds the original Gemstone MMOItem, and if you
+ * wish to actually remove the GemStone, you must do so through {@link #removeGemStone(UUID, String)}
+ *
+ * @param gem Gemstone that you believe is in here
+ * @return The gemstone as it was when inserted, or null
+ * if such gemstone is not in here.
+ * @see #extractGemstones() More optimized method for extracting all gemstones at the same time.
+ */
+ @Nullable
+ public MMOItem extractGemstone(@NotNull GemstoneData gem) {
- // If RevID updating, no need to identify stats
- if (MMOItemReforger.gemstonesRevIDWhenUnsocket)
- return pairs;
+ final MMOItem restored = MMOItems.plugin.getMMOItem(MMOItems.plugin.getTypes().get(gem.getMMOItemType()), gem.getMMOItemID());
+ if (restored == null)
+ return null;
- // Identify actual stats
- for (StatHistory hist : mergeableStatHistory.values())
- for (Pair gem : pairs) {
- final StatData historicGemData = hist.getGemstoneData(gem.getKey().getHistoricUUID());
- if (historicGemData != null)
- gem.getValue().setData(hist.getItemStat(), historicGemData);
- }
+ // If RevID updating, no need to identify stats
+ if (MMOItemReforger.gemstonesRevIDWhenUnsocket)
+ return restored;
- return pairs;
- }
+ // Identify actual stats
+ for (StatHistory hist : mergeableStatHistory.values()) {
+ final StatData historicGemData = hist.getGemstoneData(gem.getHistoricUUID());
+ if (historicGemData != null)
+ restored.setData(hist.getItemStat(), historicGemData);
+ }
- /**
- * Extracts a single gemstone. Note that this only builds the original Gemstone MMOItem, and if you
- * wish to actually remove the GemStone, you must do so through {@link #removeGemStone(UUID, String)}
- *
- * @param gem Gemstone that you believe is in here
- * @return The gemstone as it was when inserted, or null
- * if such gemstone is not in here.
- * @see #extractGemstones() More optimized method for extracting all gemstones at the same time.
- */
- @Nullable
- public MMOItem extractGemstone(@NotNull GemstoneData gem) {
+ return restored;
+ }
- final MMOItem restored = MMOItems.plugin.getMMOItem(MMOItems.plugin.getTypes().get(gem.getMMOItemType()), gem.getMMOItemID());
- if (restored == null)
- return null;
+ /**
+ * Deletes this UUID from all stat histories.
+ *
+ * @param gemUUID UUID of gem to remove
+ * @param color Color of the gem socket to restore. {@code null} to not restore socket.
+ */
+ @SuppressWarnings("ConstantConditions")
+ public void removeGemStone(@NotNull UUID gemUUID, @Nullable String color) {
- // If RevID updating, no need to identify stats
- if (MMOItemReforger.gemstonesRevIDWhenUnsocket)
- return restored;
+ // Get gemstone data
+ if (!hasData(ItemStats.GEM_SOCKETS))
+ return;
- // Identify actual stats
- for (StatHistory hist : mergeableStatHistory.values()) {
- final StatData historicGemData = hist.getGemstoneData(gem.getHistoricUUID());
- if (historicGemData != null)
- restored.setData(hist.getItemStat(), historicGemData);
- }
+ //GEM//MMOItems.log("\u00a7b-\u00a78-\u00a79-\u00a77 Extracting \u00a7e" + gemUUID.toString());
+ StatHistory gemStory = StatHistory.from(this, ItemStats.GEM_SOCKETS);
- return restored;
- }
+ /*
+ * We must only find the StatData where this gem resides,
+ * and eventually the StatHistories of the affected stats
+ * will purge themselves from extraneous gems (that are
+ * no longer registered onto the GEM_SOCKETS history).
+ */
+ if (((GemSocketsData) gemStory.getOriginalData()).removeGem(gemUUID, color))
+ return;
- /**
- * Deletes this UUID from all stat histories.
- *
- * @param gemUUID UUID of gem to remove
- * @param color Color of the gem socket to restore. {@code null} to not restore socket.
- */
- @SuppressWarnings("ConstantConditions")
- public void removeGemStone(@NotNull UUID gemUUID, @Nullable String color) {
+ // Attempt gems
+ for (UUID gemDataUUID : gemStory.getAllGemstones())
+ if (((GemSocketsData) gemStory.getGemstoneData(gemDataUUID)).removeGem(gemUUID, color))
+ return;
- // Get gemstone data
- if (!hasData(ItemStats.GEM_SOCKETS))
- return;
+ // Attempt externals
+ for (StatData externalData : gemStory.getExternalData())
+ if (((GemSocketsData) externalData).removeGem(gemUUID, color))
+ return;
- //GEM//MMOItems.log("\u00a7b-\u00a78-\u00a79-\u00a77 Extracting \u00a7e" + gemUUID.toString());
- StatHistory gemStory = StatHistory.from(this, ItemStats.GEM_SOCKETS);
-
- /*
- * We must only find the StatData where this gem resides,
- * and eventually the StatHistories of the affected stats
- * will purge themselves from extraneous gems (that are
- * no longer registered onto the GEM_SOCKETS history).
- */
- if (((GemSocketsData) gemStory.getOriginalData()).removeGem(gemUUID, color))
- return;
-
- // Attempt gems
- for (UUID gemDataUUID : gemStory.getAllGemstones())
- if (((GemSocketsData) gemStory.getGemstoneData(gemDataUUID)).removeGem(gemUUID, color))
- return;
-
- // Attempt externals
- for (StatData externalData : gemStory.getExternalData())
- if (((GemSocketsData) externalData).removeGem(gemUUID, color))
- return;
-
- // Attempt gems
- for (UUID gemDataUUID : gemStory.getAllModifiers())
- if (((GemSocketsData) gemStory.getModifiersBonus(gemDataUUID)).removeGem(gemUUID, color))
- return;
- }
- //endregion
+ // Attempt gems
+ for (UUID gemDataUUID : gemStory.getAllModifiers())
+ if (((GemSocketsData) gemStory.getModifiersBonus(gemDataUUID)).removeGem(gemUUID, color))
+ return;
+ }
+ //endregion
}
diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/data/AbilityData.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/data/AbilityData.java
index 01610d54..77b9b994 100644
--- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/data/AbilityData.java
+++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/data/AbilityData.java
@@ -168,6 +168,14 @@ public class AbilityData extends Skill {
return ability.equals(that.ability) && getTrigger().equals(that.getTrigger()) && modifiers.equals(that.modifiers);
}
+ @Override
+ public String toString() {
+ return "AbilityData{" +
+ "ability=" + ability +
+ ", modifiers=" + modifiers +
+ '}';
+ }
+
@Override
public int hashCode() {
return Objects.hash(ability, modifiers);
diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/data/AbilityListData.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/data/AbilityListData.java
index 36143462..32fb4fae 100644
--- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/data/AbilityListData.java
+++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/data/AbilityListData.java
@@ -38,7 +38,9 @@ public class AbilityListData implements StatData, Mergeable {
@NotNull
@Override
public AbilityListData clone() {
- return new AbilityListData();
+ final AbilityListData clone = new AbilityListData();
+ clone.abilities.addAll(this.abilities);
+ return clone;
}
@Override
@@ -76,6 +78,13 @@ public class AbilityListData implements StatData, Mergeable {
return true;
}
+ @Override
+ public String toString() {
+ return "AbilityListData{" +
+ "abilities=" + abilities +
+ '}';
+ }
+
@Override
public boolean isEmpty() {
return abilities.isEmpty();
diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/data/GemSocketsData.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/data/GemSocketsData.java
index 52baf3e3..c11148e6 100644
--- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/data/GemSocketsData.java
+++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/data/GemSocketsData.java
@@ -23,7 +23,7 @@ import java.util.*;
*/
public class GemSocketsData implements StatData, Mergeable, RandomStatData {
@NotNull
- private final Set gems = new LinkedHashSet<>();
+ private final List gems = new ArrayList<>();
@NotNull
private final List emptySlots;
@@ -55,7 +55,7 @@ public class GemSocketsData implements StatData, Mergeable, Rand
@Nullable
public String getEmptySocket(@NotNull String gem) {
for (String slot : emptySlots)
- if (gem.equals("") || slot.equals(getUncoloredGemSlot()) || gem.equals(slot))
+ if (gem.isEmpty() || slot.equals(getUncoloredGemSlot()) || gem.equals(slot))
return slot;
return null;
}
@@ -70,9 +70,12 @@ public class GemSocketsData implements StatData, Mergeable, Rand
gems.add(gem);
}
- public void apply(String gem, GemstoneData gemstone) {
- emptySlots.remove(getEmptySocket(gem));
+ public boolean apply(String gem, GemstoneData gemstone) {
+ final String matchingSocket = getEmptySocket(gem);
+ if (matchingSocket == null) return false;
+ emptySlots.remove(matchingSocket);
gems.add(gemstone);
+ return true;
}
public void addEmptySlot(@NotNull String slot) {
@@ -84,8 +87,18 @@ public class GemSocketsData implements StatData, Mergeable, Rand
return emptySlots;
}
- @NotNull
+ /**
+ * @see #getGems()
+ * @deprecated Gems are stored inside a list
+ * rather than inside a linked hash set.
+ */
+ @Deprecated
public Set getGemstones() {
+ return new HashSet<>(gems);
+ }
+
+ @NotNull
+ public List getGems() {
return gems;
}
diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/data/type/Mergeable.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/data/type/Mergeable.java
index 0574075d..ac1c6ce4 100644
--- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/data/type/Mergeable.java
+++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/data/type/Mergeable.java
@@ -17,7 +17,7 @@ import org.jetbrains.annotations.NotNull;
* Strongly encouraged to override the equals
method
* to something fitting here as Mergeable stats should support comparisons.
*/
-public interface Mergeable extends StatData {
+public interface Mergeable> extends StatData {
/**
* Merging two stat datas is required when an item benefits from
diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/DoubleStat.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/DoubleStat.java
index 38092e41..763fd380 100644
--- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/DoubleStat.java
+++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/DoubleStat.java
@@ -354,46 +354,14 @@ public class DoubleStat extends ItemStat impleme
@NotNull
@Override
public StatData apply(@NotNull StatData original, @NotNull UpgradeInfo info, int level) {
-
- // Must be DoubleData
- int i = level;
if (original instanceof DoubleData && info instanceof DoubleUpgradeInfo) {
-
- // Get value
+ int i = level;
double value = ((DoubleData) original).getValue();
-
- // If leveling up
- if (i > 0) {
-
- // While still positive
- while (i > 0) {
-
- // Apply PMP Operation Positively
- value = ((DoubleUpgradeInfo) info).getPMP().apply(value);
-
- // Decrease
- i--;
- }
-
- // Degrading the item
- } else if (i < 0) {
-
- // While still negative
- while (i < 0) {
-
- // Apply PMP Operation Reversibly
- value = ((DoubleUpgradeInfo) info).getPMP().reverse(value);
-
- // Decrease
- i++;
- }
- }
-
- // Update
+ while (i-- > 0) value = ((DoubleUpgradeInfo) info).getPMP().apply(value);
+ while (i++ < 0) value = ((DoubleUpgradeInfo) info).getPMP().reverse(value);
((DoubleData) original).setValue(value);
}
- // Upgraded
return original;
}
diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/StatHistory.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/StatHistory.java
index 4ed40d51..dc0e382f 100644
--- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/StatHistory.java
+++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/type/StatHistory.java
@@ -14,7 +14,6 @@ import net.Indyuce.mmoitems.api.util.message.FFPMMOItems;
import net.Indyuce.mmoitems.stat.data.EnchantListData;
import net.Indyuce.mmoitems.stat.data.GemSocketsData;
import net.Indyuce.mmoitems.stat.data.GemstoneData;
-import net.Indyuce.mmoitems.stat.data.StringListData;
import net.Indyuce.mmoitems.stat.data.type.Mergeable;
import net.Indyuce.mmoitems.stat.data.type.StatData;
import net.Indyuce.mmoitems.stat.data.type.UpgradeInfo;
@@ -43,10 +42,10 @@ public class StatHistory {
private ArrayList perExternalData = new ArrayList<>();
private HashMap perGemstoneData = new HashMap<>();
- private StatHistory(@NotNull MMOItem ofItem, @NotNull ItemStat ofStat, @NotNull StatData ogData) {
- itemStat = ofStat;
- originalData = ogData;
- parent = ofItem;
+ private StatHistory(@NotNull MMOItem parentItem, @NotNull ItemStat parentStat, @NotNull StatData parentData) {
+ itemStat = parentStat;
+ originalData = parentData;
+ parent = parentItem;
}
/**
@@ -78,36 +77,20 @@ public class StatHistory {
* @return Sure there is a Stat History and all but, does it
* actually have any information apart from the OG Data?
*/
- public boolean isClear() {
+ public boolean isEmpty() {
/*
* Enchant list data is not clear even if redundant.
- *
* Its an important assumption in several methods
- * like Enchants.separateEnchantments()
+ * like Enchants#separateEnchantments()
*/
- if (getOriginalData() instanceof EnchantListData) {
- if (((EnchantListData) getOriginalData()).getEnchants().size() != 0) {
- //CLR//MMOItems.log("\u00a7a -+- \u00a77Found Enchantments, \u00a7cnot clear. \u00a78{\u00a77" + getItemStat().getId() + "\u00a78}");
- return false;
- }
- }
-
- // Any gemstones or external SH? Then its NOT CLEAR
- if (getAllGemstones().size() > 0 || getExternalData().size() > 0 || getAllModifiers().size() > 0) {
- //CLR//MMOItems.log("\u00a7a -+- \u00a77Found Gemstones / ESH, \u00a7cnot clear. \u00a78{\u00a77" + getItemStat().getId() + "\u00a78}");
+ if (getOriginalData() instanceof EnchantListData && ((EnchantListData) getOriginalData()).getEnchants().size() != 0)
return false;
- }
- // Is it clear?
- if (getOriginalData().isEmpty() && (!isUpgradeable() || getMMOItem().getUpgradeLevel() == 0)) {
- //CLR//MMOItems.log("\u00a7a -+- \u00a77Original data is clear & unupgraded, \u00a7aclear. \u00A73(\u00a78Upgradeable? \u00a7b" + isUpgradeable() + "\u00a78, Upgrade Level:\u00a7b " + getMMOItem().getUpgradeLevel() + "\u00a73) \u00a78{\u00a77" + getItemStat().getId() + "\u00a78}");
- return true;
- }
+ // Any gemstones, external or modifier data?
+ if (getAllGemstones().size() > 0 || getExternalData().size() > 0 || getAllModifiers().size() > 0) return false;
- // Exactly the same as the MMOItem? [This check should basically always be true though]
- //CLR//if (getOriginalData().equals(getMMOItem().getData(getItemStat()))) { MMOItems.log("\u00a7a -+- \u00a77Original data has never been merged, \u00a7aclear. \u00a78{\u00a77" + getItemStat().getId() + "\u00a78}"); }
- return getOriginalData().equals(getMMOItem().getData(getItemStat()));
+ return true;
}
public void setParent(@NotNull MMOItem parent) {
@@ -119,7 +102,8 @@ public class StatHistory {
* Presumably from when it was first generated.
*/
public void setOriginalData(@NotNull StatData s) {
- originalData = Objects.requireNonNull(s, "Original data cannot be null");
+ Validate.notNull(s, "Original data cannot be null");
+ originalData = s;
}
/**
@@ -137,6 +121,8 @@ public class StatHistory {
* were rolled when the item was first created.
*/
public void registerModifierBonus(@NotNull UUID of, @NotNull StatData data) {
+ Validate.notNull(of, "Modifier UUID cannot be null");
+ Validate.notNull(data, "Stat data cannot be null");
perModifierBonus.put(of, data);
}
@@ -199,6 +185,8 @@ public class StatHistory {
* The value of this stat data will be +5.5
*/
public void registerGemstoneData(@NotNull UUID of, @NotNull StatData data) {
+ Validate.notNull(of, "Gemstone ID cannot be null");
+ Validate.notNull(data, "Stat data cannot be null");
perGemstoneData.put(of, data);
}
@@ -224,20 +212,15 @@ public class StatHistory {
return perExternalData;
}
- @Deprecated
- public void consolidateEXSH() {
- collapseExternalData();
- }
-
/**
- * Collapses all external stat datas
- * of unknown source into only one.
+ * Merges all external stat datas of unknown
+ * origin into one stat data instance.
*/
- public void collapseExternalData() {
+ public void fuseExternalData() {
// Create Clear
StatData theEXSH = getItemStat().getClearStatData();
- for (StatData ex : getExternalData()) if (ex != null) ((Mergeable) theEXSH).mergeWith(ex);
+ for (StatData ex : getExternalData()) ((Mergeable) theEXSH).mergeWith((Mergeable) ex);
// Clear and Register
getExternalData().clear();
@@ -253,6 +236,7 @@ public class StatHistory {
* Well, I guess whatever plugin is putting them here may remove them by editing the list directly with StatHistory.getExternalData()
*/
public void registerExternalData(@NotNull StatData data) {
+ Validate.notNull(data, "Stat data cannot be null");
perExternalData.add(data);
}
@@ -323,86 +307,33 @@ public class StatHistory {
original = ((Mergeable) original).clone();
//UPGRD//MMOItems.log("\u00a7a +\u00a77 Found original data\u00a7f " + original);
}
- //LVL//MMOItems.log(" \u00a7d*\u00a77-\u00a7a-\u00a763? \u00a77Lvl: \u00a7b" + parentItem.getUpgradeLevel() + "\u00a7d-\u00a77-\u00a7a-\u00a7d-\u00a77-\u00a7a-");
- // Create new
+ // Create and register new
hist = new StatHistory(parentItem, stat, original);
-
- //LVL//MMOItems.log(" \u00a7d*\u00a77-\u00a7a-\u00a764? \u00a77Lvl: \u00a7b" + parentItem.getUpgradeLevel() + "\u00a7d-\u00a77-\u00a7a-\u00a7d-\u00a77-\u00a7a-");
- // Append to the item
parentItem.setStatHistory(stat, hist);
-
- //LVL//MMOItems.log(" \u00a7d*\u00a77-\u00a7a-\u00a765? \u00a77Lvl: \u00a7b" + parentItem.getUpgradeLevel() + "\u00a7d-\u00a77-\u00a7a-\u00a7d-\u00a77-\u00a7a-");
-
- //LVL//MMOItems.log(" \u00a7d*\u00a77*\u00a7a*\u00a766? \u00a77Lvl: \u00a7b" + hist.getMMOItem().getUpgradeLevel() + "\u00a7d-\u00a77-\u00a7a-\u00a7d-\u00a77-\u00a7a-");
- // Thats it
return hist;
}
/**
* Checks the item and makes sure that the UUIDs attributed to gemstones
- * link to existing gem stones. Removes them if no such gemstone exists.
+ * link to existing gemstones. Removes them if no such gemstone exists.
*/
public void purgeGemstones() {
- // Which will get purged...
- ArrayList extraneous = new ArrayList<>();
+ // No socket history can be found => clear all gems
GemSocketsData data = (GemSocketsData) getMMOItem().getData(ItemStats.GEM_SOCKETS);
if (data == null) {
- data = new GemSocketsData(new ArrayList<>());
+ perGemstoneData.clear();
+ return;
}
- // For each UUID
- for (UUID gem : perGemstoneData.keySet()) {
-
- // Check Gemstones
- boolean success = false;
- for (GemstoneData indiv : data.getGemstones()) {
-
- // Not null
- if (indiv != null) {
-
- // Equal in UUID
- if (gem.equals(indiv.getHistoricUUID())) {
-
- success = true;
- break;
- }
- }
- }
-
- // No success?
- if (!success) {
-
- // No gemstone matched
- extraneous.add(gem);
- }
+ // Pb: intersecting between List and HashTable
+ HashMap newPerGemstoneData = new HashMap<>();
+ for (GemstoneData gemData : data.getGemstones()) {
+ final StatData found = perGemstoneData.get(gemData.getHistoricUUID());
+ if (found != null) newPerGemstoneData.put(gemData.getHistoricUUID(), found);
}
-
- // Unregister
- for (UUID ext : extraneous) {
- //RECALCULATE//MMOItems.log("\u00a76 ||\u00a77 Purged Stone: \u00a7e" + ext.toString() + "\u00a78 (\u00a73" + getItemStat().getId() + "\u00a78)");
-
- // Remove
- removeGemData(ext);
- }
- }
-
- /**
- * @return If this stat changes when the MMOItem is upgraded.
- */
- public boolean isUpgradeable() {
-
- // No upgrades no possible
- if (!getMMOItem().hasUpgradeTemplate()) {
- return false;
- }
-
- // Get Upgrade Info?
- UpgradeInfo inf = getMMOItem().getUpgradeTemplate().getUpgradeInfo(getItemStat());
-
- // No Upgrade Information? Looks like you're calculating as a normal merge stat
- return inf != null;
+ perGemstoneData = newPerGemstoneData;
}
/**
@@ -416,70 +347,21 @@ public class StatHistory {
return recalculate(true, level);
}
- /**
- * This recalculates final value of the stats of the item.
- *
- * This will not apply the changes, it will just give you the final
- * StatData
that shall be applied (used when upgrading).
- *
- * @param withPurge Check if the gemstones UUIDs are valid.
- * Leave true
unless you know
- * what you're doing.
- */
- @NotNull
- public StatData recalculate(boolean withPurge, int level) {
- //RECALCULATE//MMOItems.log("\u00a7d|||\u00a77 Recalculating \u00a7f" + getItemStat().getNBTPath() + "\u00a77, Purge? \u00a7e" + withPurge);
-
- if (withPurge) {
- purgeGemstones();
- }
-
- // If its upgradeable and not level ZERO, it must apply upgrades
- //UPGRD//MMOItems.log("\u00a7d|\u00a79|\u00a76|\u00a77 Upgradeable Requirements: ");
- //UPGRD//MMOItems.log(" \u00a76|\u00a77 Upgrade Level: \u00a7e" + level);
- //UPGRD//MMOItems.log(" \u00a76|\u00a77 Upgradeable Stat: \u00a7e" + (getItemStat() instanceof Upgradable));
- //UPGRD//MMOItems.log(" \u00a76|\u00a77 Template Exists: \u00a7e" + (getMMOItem().hasUpgradeTemplate()));
- if ((level != 0) &&
- (getItemStat() instanceof Upgradable) &&
- (getMMOItem().hasUpgradeTemplate())) {
-
- // Recalculate upgrading
- return recalculateUpgradeable(level);
- }
-
- // Merge Normally
- return recalculateMergeable();
- }
-
/**
* This recalculates values accounting only for gemstones and external data.
- *
* In case someone was wondered the contribution of upgrading the item, just
- * substract it from {@link #recalculate(int)}
+ * subtract it from {@link #recalculate(int)}.
*/
@NotNull
public StatData recalculateUnupgraded() {
- return recalculateUnupgraded(true);
+ return recalculate(true, null);
}
- /**
- * This recalculates values accounting only for gemstones and external data.
- *
- * In case someone was wondered the contribution of upgrading the item, just
- * substract it from {@link #recalculate(int)}
- *
- * @param withPurge Check if the gemstones UUIDs are valid.
- * Leave true
unless you know
- * what you're doing.
- */
- @NotNull
- public StatData recalculateUnupgraded(boolean withPurge) {
- if (withPurge) {
- purgeGemstones();
- }
-
- // Merge Normally
- return recalculateMergeable();
+ private int findLevel(int upgradeLevel, UUID gemstoneId) {
+ for (GemstoneData gemstone : getMMOItem().getGemstones())
+ if (gemstone.getHistoricUUID().equals(gemstoneId))
+ return gemstone.isScaling() ? gemstone.getLevel() : upgradeLevel;
+ throw new IllegalArgumentException("Could not find level of gem " + gemstoneId);
}
/**
@@ -492,131 +374,39 @@ public class StatHistory {
*
4: Sums Gem Stone Data (which should be scaled accordingly [Upgrades are entirely merged into their data])
* 5: Sums external data (modifiers that are not linked to an ID, I suppose by external plugins).
*/
- private StatData recalculateUpgradeable(int lvl) {
- //RECALCULATE//MMOItems.log("\u00a76|||\u00a77 Calculating \u00a7f" + getItemStat().getNBTPath() + "\u00a77 as Upgradeable");
+ @NotNull
+ public StatData recalculate(boolean purgeFirst, @Nullable Integer upgradeLevel) {
+ if (purgeFirst) purgeGemstones();
- // Get Upgrade Info?
- UpgradeInfo inf = getMMOItem().getUpgradeTemplate().getUpgradeInfo(getItemStat());
-
- // No Upgrade Information? Looks like you're calculating as a normal merge stat
- if (inf == null) {
- return recalculateMergeable();
- }
+ final UpgradeInfo upgradeInfo = upgradeLevel != null &&
+ upgradeLevel != 0 &&
+ getItemStat() instanceof Upgradable ?
+ getMMOItem().getUpgradeTemplate().getUpgradeInfo(getItemStat()) : null;
// Clone original
- StatData ogCloned = ((Mergeable) originalData).clone();
- //DBL//if (ogCloned instanceof DoubleData) MMOItems.log("\u00a76 >\u00a77 Original Base: \u00a7e" + ((DoubleData) ogCloned).getValue() + "\u00a78 {Original:\u00a77 " + ((DoubleData) getOriginalData()).getValue() + "\u00a78}");
+ Mergeable finalData = ((Mergeable) originalData).clone();
- // Add Modifiers (who are affected by upgrades as if they was the base item data
- for (UUID d : perModifierBonus.keySet()) {
-
- //DBL//if (getModifiersBonus() instanceof DoubleData) MMOItems.log("\u00a76 >\u00a7c> \u00a77 Modifier Base: \u00a7e" + ((DoubleData) getModifiersBonus()).getValue());
- // Just merge ig
- ((Mergeable) ogCloned).mergeWith(((Mergeable) getModifiersBonus(d)).clone());
- }
+ // Add modifiers (affected by upgrades as if they were base item data)
+ for (UUID modifierId : perModifierBonus.keySet()) finalData.mergeWith((Mergeable) getModifiersBonus(modifierId));
// Level up
- //RECALCULATE//MMOItems.log("\u00a76 ||\u00a77 Item Level: \u00a7e" + lvl);
- StatData ret = ((Upgradable) getItemStat()).apply(ogCloned, inf, lvl);
- //DBL//if (ret instanceof DoubleData) MMOItems.log("\u00a76 >\u00a77 Leveled Base: \u00a7e" + ((DoubleData) ret).getValue() + "\u00a78 {Original:\u00a77 " + ((DoubleData) getOriginalData()).getValue() + "\u00a78}");
+ if (upgradeInfo != null)
+ finalData = (Mergeable) ((Upgradable) getItemStat()).apply(finalData, upgradeInfo, upgradeLevel);
// Add up gemstones
- 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()) {
- if (gData == null) {
- continue;
- }
- //RECALCULATE//MMOItems.log("\u00a76 -\u00a7b-\u00a76-\u00a77 Gemstone " + gData.getName() + "\u00a77 " + gData.getHistoricUUID().toString());
-
- // Find that one of matching UUID
- if (gData.getHistoricUUID().equals(d)) {
-
- if (gData.isScaling()) {
-
- // Ok
- level = gData.getLevel();
- //RECALCULATE//MMOItems.log("\u00a76 -\u00a7b-\u00a76-\u00a7a- Found:\u00a77" + level);
-
- } else {
-
- // No scaling
- level = lvl;
- //RECALCULATE//MMOItems.log("\u00a76 -\u00a7b-\u00a76-\u00a7a- Found,\u00a77 Unscaling");
- }
- }
+ for (UUID gemstoneId : perGemstoneData.keySet()) {
+ Mergeable gsData = (Mergeable) getGemstoneData(gemstoneId);
+ if (upgradeInfo != null) {
+ int levelDifference = upgradeLevel - findLevel(upgradeLevel, gemstoneId);
+ gsData = (Mergeable) ((Upgradable) getItemStat()).apply(gsData.clone(), upgradeInfo, levelDifference);
}
-
- // Calculate level difference
- int gLevel = lvl - level;
- //RECALCULATE//MMOItems.log("\u00a76 |\u00a7b|\u00a76>\u00a77 Gemstone Level: \u00a7e" + gLevel + "\u00a77 (Put at \u00a7b" + level + "\u00a77)");
-
- //DBL//if (getGemstoneData(d) instanceof DoubleData) MMOItems.log("\u00a76 \u00a7b|>\u00a77 Gemstone Base: \u00a7e" + ((DoubleData) getGemstoneData(d)).getValue());
- // Apply upgrades
- //noinspection ConstantConditions
- StatData gRet = ((Upgradable) getItemStat()).apply(((Mergeable) getGemstoneData(d)).clone(), inf, gLevel);
- //DBL//if (gRet instanceof DoubleData) MMOItems.log("\u00a76 \u00a7b|>\u00a77 Leveled Base: \u00a7e" + ((DoubleData) gRet).getValue());
-
- // Merge
- ((Mergeable) ret).mergeWith(((Mergeable) gRet).clone());
+ finalData.mergeWith(gsData);
}
- // Add up externals (who dont suffer upgrades
- for (StatData d : getExternalData()) {
+ // Add up externals (who don't suffer upgrades)
+ for (StatData externalData : getExternalData()) finalData.mergeWith((Mergeable) externalData);
- //DBL//if (d instanceof DoubleData) MMOItems.log("\u00a76 >\u00a7c> \u00a77 Extraneous Base: \u00a7e" + ((DoubleData) d).getValue());
- // Just merge ig
- ((Mergeable) ret).mergeWith(((Mergeable) d).clone());
- }
-
- // Return result
- //DBL//if (ret instanceof DoubleData) MMOItems.log("\u00a76:::\u00a77 Result: \u00a7e" + ((DoubleData) ret).getValue() + "\u00a78 {Original:\u00a77 " + ((DoubleData) getOriginalData()).getValue() + "\u00a78}");
- return ret;
- }
-
- /**
- * This recalculates final value of the stats of the item.
- *
- * That is, it (in this order):
- * 1: Starts out with a fresh (empty) data
- *
2: Sums the original values
- * 3: Sums Gem Stone Data (which should be scaled accordingly [Upgrades are entirely merged into their data])
- * 4: Sums external data (modifiers that are not linked to an ID, I suppose by external plugins).
- */
- private StatData recalculateMergeable() {
- //RECALCULATE//MMOItems.log("\u00a73|||\u00a77 Calculating \u00a7f" + getItemStat().getNBTPath() + "\u00a77 as Mergeable");
-
- // Just clone bro
- StatData ret = ((Mergeable) getOriginalData()).clone();
-
- //DBL//if (ret instanceof DoubleData) MMOItems.log("\u00a73 > \u00a77 Original Base: \u00a7e" + ((DoubleData) ret).getValue());
-
- // Add Modifiers
- for (StatData d : perModifierBonus.values()) {
- //DBL//if (getModifiersBonus() instanceof DoubleData) MMOItems.log("\u00a73 >\u00a7c> \u00a77 Modifier Base: \u00a7e" + ((DoubleData) getModifiersBonus()).getValue());
- // Just merge ig
- ((Mergeable) ret).mergeWith(((Mergeable) d).clone());
- }
-
- // Add up gemstones
- for (StatData d : perGemstoneData.values()) {
- //DBL//if (d instanceof DoubleData) MMOItems.log("\u00a73 >\u00a7b> \u00a77 Gemstone Base: \u00a7e" + ((DoubleData) d).getValue());
- ((Mergeable) ret).mergeWith(((Mergeable) d).clone());
- }
-
- // Add up externals
- for (StatData d : getExternalData()) {
- //DBL//if (d instanceof DoubleData) MMOItems.log("\u00a73 >\u00a7c> \u00a77 Extraneous Base: \u00a7e" + ((DoubleData) d).getValue());
- ((Mergeable) ret).mergeWith(((Mergeable) d).clone());
- }
-
- // Return result
- //DBL//if (ret instanceof DoubleData) MMOItems.log("\u00a73:::\u00a77 Result: \u00a7b" + ((DoubleData) ret).getValue());
- return ret;
+ return finalData;
}
/**
@@ -632,7 +422,7 @@ public class StatHistory {
JsonObject object = new JsonObject();
// To know the stat it was
- object.addProperty(enc_Stat, getItemStat().getId());
+ object.addProperty(ENC_STAT, getItemStat().getId());
/*
* Save the original data. It is redundant to save if it is clear though.
@@ -646,7 +436,7 @@ public class StatHistory {
* StatHistory of these items.
*/
if (!getOriginalData().isEmpty() || getItemStat() == ItemStats.ENCHANTS) {
- object.add(enc_OGS, ItemTag.compressTags(getItemStat().getAppliedNBT(getOriginalData())));
+ object.add(ENC_OGS, ItemTag.compressTags(getItemStat().getAppliedNBT(getOriginalData())));
}
// Kompress Arrays
@@ -671,7 +461,7 @@ public class StatHistory {
// Include
if (gemz.size() > 0) {
- object.add(enc_GSS, gemz);
+ object.add(ENC_GSS, gemz);
}
@@ -692,7 +482,7 @@ public class StatHistory {
// Include
if (externals.size() > 0) {
- object.add(enc_EXS, externals);
+ object.add(ENC_EXS, externals);
}
// Kompress Arrays
@@ -717,7 +507,7 @@ public class StatHistory {
// Include
if (modz.size() > 0) {
- object.add(enc_MOD, modz);
+ object.add(ENC_MOD, modz);
}
@@ -756,22 +546,22 @@ public class StatHistory {
JsonElement modEncode = null;
// It has stat information right?
- if (json.has(enc_Stat)) {
- statEncode = json.get(enc_Stat);
+ if (json.has(ENC_STAT)) {
+ statEncode = json.get(ENC_STAT);
} else {
return null;
}
- if (json.has(enc_OGS)) {
- ogStatsEncode = json.get(enc_OGS);
+ if (json.has(ENC_OGS)) {
+ ogStatsEncode = json.get(ENC_OGS);
}
- if (json.has(enc_GSS)) {
- gemsEncode = json.get(enc_GSS);
+ if (json.has(ENC_GSS)) {
+ gemsEncode = json.get(ENC_GSS);
}
- if (json.has(enc_EXS)) {
- extEncode = json.get(enc_EXS);
+ if (json.has(ENC_EXS)) {
+ extEncode = json.get(ENC_EXS);
}
- if (json.has(enc_MOD)) {
- modEncode = json.get(enc_MOD);
+ if (json.has(ENC_MOD)) {
+ modEncode = json.get(ENC_MOD);
}
// It is a primitive right
@@ -960,21 +750,12 @@ public class StatHistory {
@Nullable
public static StatHistory fromNBTString(@NotNull MMOItem iSource, @NotNull String codedJson) {
- // Attempt
try {
-
- // Make JSON Parser
JsonParser pJSON = new JsonParser();
-
- // Parse as array
JsonObject oJSON = pJSON.parse(codedJson).getAsJsonObject();
-
- // Bake
return fromJson(iSource, oJSON);
} catch (Throwable e) {
-
- // Feedbacc
FriendlyFeedbackProvider ffp = new FriendlyFeedbackProvider(FFPMMOItems.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());
@@ -983,53 +764,6 @@ public class StatHistory {
}
}
- /**
- * Get all gemstone and extraneous data from this other, while
- * keeping the current ones as well as these original bases.
- *
- * Fails if the stats are not the same one.
- */
- @Deprecated
- public void assimilate(@NotNull StatHistory other) {
-
- // Stat must be the same
- if (other.getItemStat().getNBTPath().equals(getItemStat().getNBTPath())) {
- //UPDT//MMOItems.log(" \u00a72>\u00a76> \u00a77History Stat Matches");
-
- //UPDT//MMOItems.log(" \u00a76:\u00a72: \u00a77Original Gemstones \u00a7f" + perGemstoneData.size());
- //UPDT//MMOItems.log(" \u00a76:\u00a72: \u00a77Original Externals \u00a7f" + perExternalData.size());
-
- // Register gemstones
- for (UUID exUID : other.getAllGemstones()) {
- //noinspection ConstantConditions
- registerGemstoneData(exUID, other.getGemstoneData(exUID));
- }
-
- // Register externals
- for (StatData ex : other.getExternalData()) {
- registerExternalData((ex));
- }
-
- // Register modifiers
- for (UUID exUID : other.getAllModifiers()) {
- //noinspection ConstantConditions
- registerModifierBonus(exUID, other.getModifiersBonus(exUID));
- }
-
- //UPDT//MMOItems.log(" \u00a76:\u00a72: \u00a77Final Gemstones \u00a7f" + perGemstoneData.size());
- //UPDT//MMOItems.log(" \u00a76:\u00a72: \u00a77Final Externals \u00a7f" + perExternalData.size());
- //ASS//MMOItems.log(" \u00a76:\u00a72: \u00a77Assimiliaton Result \u00a7f");
- //ASS//log();
- }
- }
-
- @Deprecated
- public StatHistory clone(@NotNull MMOItem newParent) {
- final StatHistory his = clone();
- his.setParent(newParent);
- return his;
- }
-
@SuppressWarnings("MethodDoesntCallSuperMethod")
@NotNull
public StatHistory clone() {
@@ -1042,88 +776,51 @@ public class StatHistory {
return res;
}
- static final String enc_Stat = "Stat";
- static final String enc_OGS = "OGStory";
- static final String enc_GSS = "Gemstory";
- static final String enc_EXS = "Exstory";
- static final String enc_MOD = "Mod";
+ private static final String ENC_STAT = "Stat", ENC_OGS = "OGStory", ENC_GSS = "Gemstory", ENC_EXS = "Exstory", ENC_MOD = "Mod";
- /**
- * Logs into the console. Dev Method
- */
- @Deprecated
- public void log() {
-
- MMOItems.print(null, "\u00a76SH of \u00a7e" + getItemStat().getId() + "\u00a77, \u00a7b" + getMMOItem().getType() + " " + getMMOItem().getId(), null);
-
- if (getOriginalData() instanceof StringListData) {
-
- MMOItems.print(null, "\u00a7a++ Original", null);
- for (String str : ((StringListData) getOriginalData()).getList()) {
- MMOItems.print(null, "\u00a7a ++\u00a77 " + str, null);
- }
-
- MMOItems.print(null, "\u00a7e++ Gemstones", null);
- for (UUID ui : getAllGemstones()) {
- StatData sd = getGemstoneData(ui);
- if (!(sd instanceof StringListData)) {
- continue;
- }
- for (String str : ((StringListData) sd).getList()) {
- MMOItems.print(null, "\u00a7e ++\u00a77 " + str, null);
- }
- }
-
- MMOItems.print(null, "\u00a7c++ ExSH", null);
- for (StatData sd : getExternalData()) {
- if (!(sd instanceof StringListData)) {
- continue;
- }
- for (String str : ((StringListData) sd).getList()) {
- MMOItems.print(null, "\u00a7e ++\u00a77 " + str, null);
- }
- }
-
- MMOItems.print(null, "\u00a7d++ Modifiers", null);
- for (UUID ui : getAllModifiers()) {
- StatData sd = getModifiersBonus(ui);
- if (!(sd instanceof StringListData)) {
- continue;
- }
- for (String str : ((StringListData) sd).getList()) {
- MMOItems.print(null, "\u00a7d ++\u00a77 " + str, null);
- }
- }
- } else {
-
- MMOItems.print(null, "\u00a7a-- Original", null);
- MMOItems.print(null, "\u00a7a ++\u00a77 " + getOriginalData(), null);
-
- MMOItems.print(null, "\u00a7e-- Gemstones", null);
- for (UUID ui : getAllGemstones()) {
- StatData sd = getGemstoneData(ui);
- if (sd == null) {
- continue;
- }
- MMOItems.print(null, "\u00a7e ++\u00a77 " + sd, null);
- }
-
- MMOItems.print(null, "\u00a7c-- ExSH", null);
- for (StatData sd : getExternalData()) {
- if (sd == null) {
- continue;
- }
- MMOItems.print(null, "\u00a7e ++\u00a77 " + sd, null);
- }
-
- MMOItems.print(null, "\u00a7d-- Modifiers", null);
- for (UUID ui : getAllModifiers()) {
- StatData sd = getModifiersBonus(ui);
- if (sd == null) {
- continue;
- }
- MMOItems.print(null, "\u00a7d ++\u00a77 " + sd, null);
- }
+ //region Methods not used
+ public void assimilate(@NotNull StatHistory other) {
+ if (other.getItemStat().getNBTPath().equals(getItemStat().getNBTPath())) {
+ for (UUID exUID : other.getAllGemstones()) registerGemstoneData(exUID, other.getGemstoneData(exUID));
+ for (StatData ex : other.getExternalData()) registerExternalData((ex));
+ for (UUID exUID : other.getAllModifiers()) registerModifierBonus(exUID, other.getModifiersBonus(exUID));
}
}
+
+ /**
+ * @deprecated use {@link #clone()} followed by {@link #setParent(MMOItem)}
+ */
+ @Deprecated
+ public StatHistory clone(@NotNull MMOItem newParent) {
+ final StatHistory his = clone();
+ his.setParent(newParent);
+ return his;
+ }
+
+ @NotNull
+ @Deprecated
+ public StatData recalculateUnupgraded(boolean withPurge) {
+ return recalculate(withPurge, null);
+ }
+
+ /**
+ * @see #isEmpty()
+ */
+ @Deprecated
+ public boolean isClear() {
+ return isEmpty();
+ }
+
+ /**
+ * @see #fuseExternalData()
+ */
+ @Deprecated
+ public void consolidateEXSH() {
+ fuseExternalData();
+ }
+
+ public boolean isUpgradeable() {
+ return getMMOItem().hasUpgradeTemplate() && getMMOItem().getUpgradeTemplate().getUpgradeInfo(getItemStat()) != null;
+ }
+ //endregion
}