diff --git a/src/main/java/net/Indyuce/mmoitems/api/Type.java b/src/main/java/net/Indyuce/mmoitems/api/Type.java index 71f545f6..e07691a9 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/Type.java +++ b/src/main/java/net/Indyuce/mmoitems/api/Type.java @@ -11,6 +11,7 @@ import org.apache.commons.lang.Validate; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; import java.util.ArrayList; @@ -55,15 +56,22 @@ public class Type { public static final Type ACCESSORY = new Type(TypeSet.EXTRA, "ACCESSORY", false, EquipmentSlot.ACCESSORY); public static final Type BLOCK = new Type(TypeSet.EXTRA, "BLOCK", false, EquipmentSlot.OTHER); - private final String id; + @NotNull private final String id; private String name; - private final TypeSet set; + @NotNull private final TypeSet set; - public boolean isFourGUIMode() { - return fourGUIMode; - } - private final boolean fourGUIMode; + /** + * @return Does it display as four rows in /mmoitems browse? + */ + public boolean isFourGUIMode() { return fourGUIMode; } + private boolean fourGUIMode; + + /** + * @return Default lore format used by this Type + */ + @Nullable public String getLoreFormat() { return loreFormat; } + @Nullable private String loreFormat; /** * Used for item type restrictions for gem stones to easily check if the @@ -71,7 +79,7 @@ public class Type { */ private final boolean weapon; - private final EquipmentSlot equipType; + @NotNull private final EquipmentSlot equipType; /** * Used to display the item in the item explorer and in the item recipes @@ -97,34 +105,66 @@ public class Type { public Type(TypeSet set, String id, boolean weapon, EquipmentSlot equipType) { this(set, id, weapon, equipType, false); } - public Type(TypeSet set, String id, boolean weapon, EquipmentSlot equipType, boolean fourGUI) { + public Type(@NotNull TypeSet set, @NotNull String id, boolean weapon, @NotNull EquipmentSlot equipType, boolean fourGUI) { this.set = set; this.id = id.toUpperCase().replace("-", "_").replace(" ", "_"); this.equipType = equipType; this.fourGUIMode = fourGUI; this.weapon = weapon; + this.loreFormat = null; + + //TYP//MMOItems.log("\u00a78TYPE \u00a75HARDCODED\u00a77 Registering\u00a7f " + id); + //TYP//MMOItems.log("\u00a78TYPE \u00a75HARDCODED\u00a77 > 4GUI\u00a7b " + fourGUIMode); + //TYP//MMOItems.log("\u00a78TYPE \u00a75HARDCODED\u00a77 > Lore\u00a7b " + loreFormat); } - public Type(TypeManager manager, ConfigurationSection config) { + public Type(@NotNull TypeManager manager,@NotNull ConfigurationSection config) { id = config.getName().toUpperCase().replace("-", "_").replace(" ", "_"); - parent = manager.get(config.getString("parent").toUpperCase().replace("-", "_").replace(" ", "_")); - set = parent.set; - weapon = parent.weapon; - equipType = parent.equipType; - this.fourGUIMode = config.getBoolean("AlternateGUIMode", parent.fourGUIMode); + parent = manager.get(config.getString("parent", "").toUpperCase().replace("-", "_").replace(" ", "_")); + + // Parent existed? + //TYP//MMOItems.log("\u00a78TYPE \u00a72CONFIG\u00a77 Reading config overrides for\u00a7f " + id + "\u00a78 (parent\u00a77 " + parent + "\u00a78)"); + + set = (parent != null ? parent.set : TypeSet.EXTRA); + weapon = (parent != null && parent.weapon); + equipType = (parent != null ? parent.equipType : EquipmentSlot.OTHER); + this.fourGUIMode = config.getBoolean("AlternateGUIMode", (parent != null && parent.fourGUIMode)); + this.loreFormat = config.getString("LoreFormat", (parent != null ? parent.loreFormat : null)); + + // Parent existed? + //TYP//MMOItems.log("\u00a78TYPE \u00a72CONFIG\u00a77 > Type\u00a7f " + equipType.toString()); + //TYP//MMOItems.log("\u00a78TYPE \u00a72CONFIG\u00a77 > 4GUI\u00a7b " + fourGUIMode); + //TYP//MMOItems.log("\u00a78TYPE \u00a72CONFIG\u00a78 >>> Config \u00a79 " + config.getBoolean("AlternateGUIMode")); + //TYP//MMOItems.log("\u00a78TYPE \u00a72CONFIG\u00a78 >>> Parent \u00a79 " + (parent == null ? "" : parent.fourGUIMode)); + //TYP//MMOItems.log("\u00a78TYPE \u00a72CONFIG\u00a77 > Lore\u00a7b " + loreFormat); + //TYP//MMOItems.log("\u00a78TYPE \u00a72CONFIG\u00a78 >>> Config \u00a79 " + config.getString("LoreFormat")); + //TYP//MMOItems.log("\u00a78TYPE \u00a72CONFIG\u00a78 >>> Parent \u00a79 " + (parent == null ? "" : parent.loreFormat)); } public void load(ConfigurationSection config) { Validate.notNull(config, "Could not find config for " + getId()); - name = config.getString("name"); - Validate.notNull(name, "Could not read name"); + // Parent existed? + //TYP//MMOItems.log("\u00a78TYPE \u00a7aLOAD\u00a77 Loading config overrides for\u00a7f " + id + "\u00a78 (parent\u00a77 " + parent + "\u00a78)"); - item = read(config.getString("display")); - Validate.notNull(item, "Could not read item"); + name = config.getString("name", name); + item = read(config.getString("display", item == null ? Material.STONE.toString() : item.getType().toString())); (unidentifiedTemplate = new UnidentifiedItem(this)).update(config.getConfigurationSection("unident-item")); + + // Getting overridden? + fourGUIMode = config.getBoolean("AlternateGUIMode", (parent != null && parent.fourGUIMode) || fourGUIMode); + loreFormat = config.getString("LoreFormat", (parent != null ? parent.loreFormat : loreFormat)); + + // Parent existed? + //TYP//MMOItems.log("\u00a78TYPE \u00a7aLOAD\u00a77 > Type\u00a7f " + equipType.toString()); + //TYP//MMOItems.log("\u00a78TYPE \u00a7aLOAD\u00a77 > 4GUI\u00a7b " + fourGUIMode); + //TYP//MMOItems.log("\u00a78TYPE \u00a7aLOAD\u00a78 >>> Config \u00a79 " + config.getBoolean("AlternateGUIMode")); + //TYP//MMOItems.log("\u00a78TYPE \u00a7aLOAD\u00a78 >>> Parent \u00a79 " + (parent == null ? "" : parent.fourGUIMode)); + //TYP//MMOItems.log("\u00a78TYPE \u00a7aLOAD\u00a77 > Lore\u00a7b " + loreFormat); + //TYP//MMOItems.log("\u00a78TYPE \u00a7aLOAD\u00a78 >>> Config \u00a79 " + config.getString("LoreFormat")); + //TYP//MMOItems.log("\u00a78TYPE \u00a7aLOAD\u00a78 >>> Parent \u00a79 " + (parent == null ? "" : parent.loreFormat)); } /** diff --git a/src/main/java/net/Indyuce/mmoitems/api/item/build/ItemStackBuilder.java b/src/main/java/net/Indyuce/mmoitems/api/item/build/ItemStackBuilder.java index c29fead8..5624e244 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/item/build/ItemStackBuilder.java +++ b/src/main/java/net/Indyuce/mmoitems/api/item/build/ItemStackBuilder.java @@ -67,8 +67,8 @@ public class ItemStackBuilder { // Gets a lore builder, which will be used to apply the chosen lore format (Choose with the lore format stat, or the default one if unspecified) lore = new LoreBuilder(mmoitem.hasData(ItemStats.LORE_FORMAT) - ? MMOItems.plugin.getFormats().getFormat(mmoitem.getData(ItemStats.LORE_FORMAT).toString()) - : MMOItems.plugin.getLanguage().getDefaultLoreFormat()); + ? MMOItems.plugin.getFormats().getFormat(mmoitem.getData(ItemStats.LORE_FORMAT).toString(), mmoitem.getType().getLoreFormat()) + : MMOItems.plugin.getFormats().getFormat(mmoitem.getType().getLoreFormat())); // Gets the meta, and hides attributes meta = item.getItemMeta(); diff --git a/src/main/java/net/Indyuce/mmoitems/manager/CraftingManager.java b/src/main/java/net/Indyuce/mmoitems/manager/CraftingManager.java index dcd6726a..ddcc8c7a 100644 --- a/src/main/java/net/Indyuce/mmoitems/manager/CraftingManager.java +++ b/src/main/java/net/Indyuce/mmoitems/manager/CraftingManager.java @@ -104,7 +104,7 @@ public class CraftingManager implements Reloadable { try { CraftingStation station = new CraftingStation(file.getName().substring(0, file.getName().length() - 4), YamlConfiguration.loadConfiguration(file)); stations.put(station.getId(), station); - } catch (IllegalArgumentException exception) { + } catch (IllegalArgumentException|NullPointerException exception) { MMOItems.plugin.getLogger().log(Level.WARNING, "Could not load station '" + file.getName() + "': " + exception.getMessage()); } diff --git a/src/main/java/net/Indyuce/mmoitems/manager/LoreFormatManager.java b/src/main/java/net/Indyuce/mmoitems/manager/LoreFormatManager.java index 94b14cae..e5e585c5 100644 --- a/src/main/java/net/Indyuce/mmoitems/manager/LoreFormatManager.java +++ b/src/main/java/net/Indyuce/mmoitems/manager/LoreFormatManager.java @@ -1,9 +1,12 @@ package net.Indyuce.mmoitems.manager; import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.api.Type; import org.apache.commons.lang.Validate; import org.bukkit.configuration.file.YamlConfiguration; +import org.jetbrains.annotations.NotNull; +import javax.annotation.Nullable; import java.io.File; import java.util.Collection; import java.util.HashMap; @@ -27,7 +30,8 @@ public class LoreFormatManager implements Reloadable { } } - public boolean hasFormat(String id) { + public boolean hasFormat(@Nullable String id) { + if (id == null) { return false; } return formats.containsKey(id); } @@ -35,8 +39,24 @@ public class LoreFormatManager implements Reloadable { return formats.values(); } - public List getFormat(String id) { - if(!hasFormat(id)) return MMOItems.plugin.getLanguage().getDefaultLoreFormat(); - return formats.get(id); + /** + * Find a lore format file by specifying its name + * + * @param prioritizedFormatNames The names of the formats to search. + * + * @return The lore format first found from the ones specified, or the default one. + */ + @NotNull public List getFormat(@NotNull String... prioritizedFormatNames) { + + /* + * Check each specified lore format in order, the first one + * to succeed will be the winner. + */ + for (String format : prioritizedFormatNames) { + if (hasFormat(format)) { return formats.get(format); } + } + + // No lore format found / specified. Go with default. + return MMOItems.plugin.getLanguage().getDefaultLoreFormat(); } } diff --git a/src/main/java/net/Indyuce/mmoitems/stat/type/StatHistory.java b/src/main/java/net/Indyuce/mmoitems/stat/type/StatHistory.java index c1399fc0..d1d03b7d 100644 --- a/src/main/java/net/Indyuce/mmoitems/stat/type/StatHistory.java +++ b/src/main/java/net/Indyuce/mmoitems/stat/type/StatHistory.java @@ -1,9 +1,6 @@ package net.Indyuce.mmoitems.stat.type; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; +import com.google.gson.*; import io.lumine.mythic.lib.api.item.ItemTag; import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackCategory; import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackProvider; @@ -12,9 +9,7 @@ import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOUtils; import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem; 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.*; import net.Indyuce.mmoitems.stat.data.type.Mergeable; import net.Indyuce.mmoitems.stat.data.type.StatData; import net.Indyuce.mmoitems.stat.data.type.UpgradeInfo; @@ -35,29 +30,12 @@ import java.util.*; */ @SuppressWarnings({"unused", "SpellCheckingInspection"}) public class StatHistory { + + /* + * Which stat is this the history of? + */ + @NotNull private final ItemStat itemStat; - private final MMOItem parent; - - /** - * The final modifier being provided by each gemstone. - * GemStones may have scaled with upgrades, that will be accounted for. - *

- * Gem stones all have a UUID bound to them so that MI knows - * what modifiers to take away when removing gem stones. - */ - public final HashMap perGemstoneData = new HashMap<>(); - - /** - * The total bonus given by modifiers that - * were rolled when the item was first created. - */ - public final HashMap perModifierBonus = new HashMap<>(); - - private static final String enc_Stat = "Stat"; - private static final String enc_OGS = "OGStory"; - private static final String enc_GSS = "Gemstory"; - private static final String enc_EXS = "Exstory"; - private static final String enc_MOD = "Mod"; /** * Which stat is this the history of? @@ -69,7 +47,7 @@ public class StatHistory { /** * @return Sure there is a Stat History and all but, does it - * actually have any information apart from the OG Data? + * actually have any information apart from the OG Data? */ public boolean isClear() { @@ -103,6 +81,11 @@ public class StatHistory { return getOriginalData().equals(getMMOItem().getData(getItemStat())); } + /* + * What MMOItem is this StatHistory linked to? + */ + @NotNull + MMOItem parent; /** * What MMOItem is this StatHistory linked to? @@ -141,9 +124,16 @@ public class StatHistory { originalData = s; } + /** + * The total bonus given by modifiers that + * were rolled when the item was first created. + */ + @NotNull + public HashMap perModifierBonus = new HashMap<>(); + /** * @return The total bonus given by modifiers that - * were rolled when the item was first created. + * were rolled when the item was first created. */ @Contract("null -> null") @Nullable @@ -179,14 +169,17 @@ public class StatHistory { public ArrayList getAllModifiers() { return new ArrayList<>(perModifierBonus.keySet()); } - /** * Clears modifier data. No way to undo so be wary of using. */ - public void clearModifiersBonus() { - perModifierBonus.clear(); - } + public void clearModifiersBonus() { perModifierBonus.clear(); } + /* + * The final modifier being provided by each gemstone. + * GemStones may have scaled with upgrades, that will be accounted for. + */ + @NotNull + public HashMap perGemstoneData = new HashMap<>(); /** * The final modifier being provided by each gemstone. * GemStones may have scaled with upgrades, that will be accounted for. @@ -199,24 +192,17 @@ public class StatHistory { } return perGemstoneData.get(of); } - /** * Removes the gem of such UUID from those registered. * * @param of UUID of the gem to remove. */ - public void removeGemData(@NotNull UUID of) { - perGemstoneData.remove(of); - } - + public void removeGemData(@NotNull UUID of) { perGemstoneData.remove(of); } /** * All the Stat Datas provided by GemStones */ @NotNull - public ArrayList getAllGemstones() { - return new ArrayList<>(perGemstoneData.keySet()); - } - + public ArrayList getAllGemstones() { return new ArrayList<>(perGemstoneData.keySet()); } /** * The final modifier being provided by each gemstone. * GemStones may have scaled with upgrades, that will be accounted for. @@ -225,16 +211,11 @@ public class StatHistory { *

originally +5, now at level 2, with +0.25 per level

* The value of this stat data will be +5.5 */ - public void registerGemstoneData(@NotNull UUID of, @NotNull StatData data) { - perGemstoneData.put(of, data); - } - + public void registerGemstoneData(@NotNull UUID of, @NotNull StatData data) { perGemstoneData.put(of, data); } /** * Clears gemstone data. No way to undo so be wary of using. */ - public void clearGemstones() { - perGemstoneData.clear(); - } + public void clearGemstones() { perGemstoneData.clear(); } /* * Modifiers of unknown origin. @@ -254,10 +235,7 @@ public class StatHistory { * Well, I guess whatever plugin is putting them here may remove them by editing the list directly with StatHistory.getExternalData() */ @NotNull - public ArrayList getExternalData() { - return perExternalData; - } - + public ArrayList getExternalData() { return perExternalData; } /** * Collapses all ExSH stat data into one. */ @@ -278,7 +256,6 @@ public class StatHistory { getExternalData().clear(); registerExternalData(theEXSH); } - /** * Modifiers of unknown origin. * Presumably put here by external plugins I guess. @@ -287,16 +264,11 @@ public class StatHistory { *

They act as gem stones, adding together to produce the total of the item, but cannot be removed, since there is no way to tell them from each other.

* 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) { - perExternalData.add(data); - } - + public void registerExternalData(@NotNull StatData data) { perExternalData.add(data); } /** * Clears exsh data. No way to undo so be wary of using. */ - public void clearExternalData() { - perExternalData.clear(); - } + public void clearExternalData() { perExternalData.clear(); } /** * Gets the stat history of this item. The stat must be Mergeable @@ -309,11 +281,7 @@ public class StatHistory { * @param ofItem MMOItem to extract stat history from * @param ofStat Stat of which to make history */ - @NotNull - public static StatHistory from(@NotNull MMOItem ofItem, @NotNull ItemStat ofStat) { - return from(ofItem, ofStat, false); - } - + @NotNull public static StatHistory from(@NotNull MMOItem ofItem, @NotNull ItemStat ofStat) { return from(ofItem, ofStat, false); } /** * Gets the stat history of this item. The stat must be Mergeable *

@@ -322,8 +290,8 @@ public class StatHistory { *

* Make sure the item has the stat present * - * @param ofItem MMOItem to extract stat history from - * @param ofStat Stat of which to make history + * @param ofItem MMOItem to extract stat history from + * @param ofStat Stat of which to make history * @param forceNew Only if you know what you are doing, set to true to not check if the item already has stat history of this stat. */ @NotNull @@ -338,9 +306,7 @@ public class StatHistory { if (hist != null) { //UPGRD//MMOItems.log("Found Stat History of \u00a76" + ofStat.getNBTPath() + "\u00a77 in this \u00a7c" + ofItem.getType().getName() + " " + ofItem.getId()); //UPGRD//hist.log(); - return hist; - } - } + return hist; } } // That is Mergeable right... //UPGRD//MMOItems.log("\u00a7aCreated Hisotry of \u00a76" + ofStat.getNBTPath() + "\u00a7a of this \u00a7c" + ofItem.getType().getName() + " " + ofItem.getId()); @@ -359,7 +325,7 @@ public class StatHistory { //UPGRD//MMOItems.log("\u00a7a +\u00a77 Found original data\u00a7f " + original); } //LVL//MMOItems.log(" \u00a7d*\u00a77-\u00a7a-\u00a763? \u00a77Lvl: \u00a7b" + ofItem.getUpgradeLevel() + "\u00a7d-\u00a77-\u00a7a-\u00a7d-\u00a77-\u00a7a-"); - + // Create new hist = new StatHistory(ofItem, ofStat, original); @@ -379,11 +345,7 @@ public class StatHistory { *

* Use StatHistory.From() to get the stat history associated to an item. */ - public StatHistory(@NotNull MMOItem ofItem, @NotNull ItemStat ofStat, @NotNull StatData ogData) { - itemStat = ofStat; - originalData = ogData; - parent = ofItem; - } + public StatHistory(@NotNull MMOItem ofItem, @NotNull ItemStat ofStat, @NotNull StatData ogData) { itemStat = ofStat; originalData = ogData; parent = ofItem; } /** * Checks the item and makes sure that the UUIDs @@ -395,9 +357,7 @@ public class StatHistory { // Which will get purged... ArrayList extraneous = new ArrayList<>(); GemSocketsData data = (GemSocketsData) getMMOItem().getData(ItemStats.GEM_SOCKETS); - if (data == null) { - data = new GemSocketsData(new ArrayList<>()); - } + if (data == null) { data = new GemSocketsData(new ArrayList<>()); } // For each UUID for (UUID gem : perGemstoneData.keySet()) { @@ -441,9 +401,7 @@ public class StatHistory { public boolean isUpgradeable() { // No upgrades no possible - if (!getMMOItem().hasUpgradeTemplate()) { - return false; - } + if (!getMMOItem().hasUpgradeTemplate()) { return false; } // Get Upgrade Info? UpgradeInfo inf = getMMOItem().getUpgradeTemplate().getUpgradeInfo(getItemStat()); @@ -458,42 +416,34 @@ public class StatHistory { * This will not apply the changes, it will just give you the final * StatData that shall be applied (used when upgrading). */ - @NotNull - public StatData recalculate(int level) { - return recalculate(true, level); - } - + @NotNull public StatData recalculate(int level) { 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) { + @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 (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())) { - + if ((level != 0) && + (getItemStat() instanceof Upgradable) && + (getMMOItem().hasUpgradeTemplate())) { + // Recalculate upgrading return recalculateUpgradeable(level); - } - + } + // Merge Normally return recalculateMergeable(); } @@ -504,26 +454,19 @@ public class StatHistory { * In case someone was wondered the contribution of upgrading the item, just * substract it from {@link #recalculate(int)} */ - @NotNull - public StatData recalculateUnupgraded() { - return recalculateUnupgraded(true); - } + @NotNull public StatData recalculateUnupgraded() { return recalculateUnupgraded(true); } /** * 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(); - } + @NotNull public StatData recalculateUnupgraded(boolean withPurge) { + if (withPurge) { purgeGemstones(); } // Merge Normally return recalculateMergeable(); @@ -546,9 +489,7 @@ public class StatHistory { UpgradeInfo inf = getMMOItem().getUpgradeTemplate().getUpgradeInfo(getItemStat()); // No Upgrade Information? Looks like you're calculating as a normal merge stat - if (inf == null) { - return recalculateMergeable(); - } + if (inf == null) { return recalculateMergeable(); } // Clone original StatData ogCloned = ((Mergeable) originalData).cloneData(); @@ -575,9 +516,7 @@ public class StatHistory { // Whats this gemstone's upgrade level? for (GemstoneData gData : getMMOItem().getGemStones()) { - if (gData == null) { - continue; - } + if (gData == null) { continue; } //RECALCULATE//MMOItems.log("\u00a76 -\u00a7b-\u00a76-\u00a77 Gemstone " + gData.getName() + "\u00a77 " + gData.getHistoricUUID().toString()); // Find that one of matching UUID @@ -638,10 +577,10 @@ public class StatHistory { //RECALCULATE//MMOItems.log("\u00a73|||\u00a77 Calculating \u00a7f" + getItemStat().getNBTPath() + "\u00a77 as Mergeable"); // Just clone bro - StatData ret = ((Mergeable) getOriginalData()).cloneData(); + StatData ret = ((Mergeable) getOriginalData()).cloneData(); //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()); @@ -658,8 +597,7 @@ public class StatHistory { // 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).merge(((Mergeable) d).cloneData()); - } + ((Mergeable) ret).merge(((Mergeable) d).cloneData()); } // Return result //DBL//if (ret instanceof DoubleData) MMOItems.log("\u00a73:::\u00a77 Result: \u00a7b" + ((DoubleData) ret).getValue()); @@ -674,17 +612,24 @@ public class StatHistory { *

* Still don't abuse calls to this. Try to do so only when necessary */ - @NotNull - public JsonObject toJson() { + @NotNull public JsonObject toJson() { JsonObject object = new JsonObject(); // To know the stat it was object.addProperty(enc_Stat, getItemStat().getId()); - // Original data - if (!((Mergeable) getOriginalData()).isClear()) { - object.add(enc_OGS, ItemTag.compressTags(getItemStat().getAppliedNBT(getOriginalData()))); - } + /* + * Save the original data. It is redundant to save if it is clear though. + * + * Except if it is the ENCHANTS ItemStat, in which a clear data must be saved + * so that we can know which enchantments came from vanilla sources (like the + * enchantment table) instead of being born with the MMOItem template. + * + * This is an assumption made by net.Indyuce.mmoitems.stat.Enchants.separateEnchantments() + * And allows net.Indyuce.mmoitems.stat.Enchants.whenLoaded() to correctly initialize the + * StatHistory of these items. + */ + if (!((Mergeable) getOriginalData()).isClear() || getItemStat() == ItemStats.ENCHANTS) { object.add(enc_OGS, ItemTag.compressTags(getItemStat().getAppliedNBT(getOriginalData()))); } // Kompress Arrays JsonArray gemz = new JsonArray(); @@ -707,9 +652,7 @@ public class StatHistory { } // Include - if (gemz.size() > 0) { - object.add(enc_GSS, gemz); - } + if (gemz.size() > 0) { object.add(enc_GSS, gemz); } // Kompress Arrays @@ -719,18 +662,14 @@ public class StatHistory { for (StatData ex : getExternalData()) { // Skip clear - if (((Mergeable) ex).isClear()) { - continue; - } + if (((Mergeable) ex).isClear()) { continue; } // Put externals.add(ItemTag.compressTags(getItemStat().getAppliedNBT(ex))); } // Include - if (externals.size() > 0) { - object.add(enc_EXS, externals); - } + if (externals.size() > 0) { object.add(enc_EXS, externals); } // Kompress Arrays JsonArray modz = new JsonArray(); @@ -753,9 +692,7 @@ public class StatHistory { } // Include - if (modz.size() > 0) { - object.add(enc_MOD, modz); - } + if (modz.size() > 0) { object.add(enc_MOD, modz); } return object; @@ -769,8 +706,7 @@ public class StatHistory { *

* Still don't abuse calls to this. Try to do so only when necessary */ - @NotNull - public String toNBTString() { + @NotNull public String toNBTString() { // Just convert to string :thinking: return toJson().toString(); @@ -779,54 +715,30 @@ public class StatHistory { /** * To read from NBT data. This undoes {@link #toJson()} basically. *

- * * @param iSource The MMOItem you are trying to read the NBT of */ - @Nullable - public static StatHistory fromJson(@NotNull MMOItem iSource, @NotNull JsonObject json) { + @Nullable public static StatHistory fromJson(@NotNull MMOItem iSource, @NotNull JsonObject json) { // Get the stat we're searching for JsonElement statEncode; - JsonElement ogStatsEncode = null; + JsonElement ogStatsEncode= null; JsonElement gemsEncode = null; JsonElement extEncode = null; JsonElement modEncode = null; // It has stat information right? - 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_GSS)) { - gemsEncode = json.get(enc_GSS); - } - if (json.has(enc_EXS)) { - extEncode = json.get(enc_EXS); - } - if (json.has(enc_MOD)) { - modEncode = json.get(enc_MOD); - } + 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_GSS)) { gemsEncode = json.get(enc_GSS); } + if (json.has(enc_EXS)) { extEncode = json.get(enc_EXS); } + if (json.has(enc_MOD)) { modEncode = json.get(enc_MOD); } // It is a primitive right - if (!statEncode.isJsonPrimitive()) { - return null; - } - if (ogStatsEncode != null && !ogStatsEncode.isJsonArray()) { - return null; - } - if (gemsEncode != null && !gemsEncode.isJsonArray()) { - return null; - } - if (extEncode != null && !extEncode.isJsonArray()) { - return null; - } - if (modEncode != null && !modEncode.isJsonArray()) { - return null; - } + if (!statEncode.isJsonPrimitive()) { return null; } + if (ogStatsEncode != null && !ogStatsEncode.isJsonArray()) { return null; } + if (gemsEncode != null && !gemsEncode.isJsonArray()) { return null; } + if (extEncode != null && !extEncode.isJsonArray()) { return null; } + if (modEncode != null && !modEncode.isJsonArray()) { return null; } // Get string String statInternalName = statEncode.getAsJsonPrimitive().getAsString(); @@ -835,9 +747,7 @@ public class StatHistory { ItemStat stat = MMOItems.plugin.getStats().get(statInternalName); // Nope - if (stat == null) { - return null; - } + if (stat == null) { return null; } // To know the stat it was StatData sData; @@ -847,7 +757,7 @@ public class StatHistory { ArrayList ogDecoded = ItemTag.decompressTags(ogStatsEncode.getAsJsonArray()); sData = stat.getLoadedNBT(ogDecoded); - // OG Not included (because its clear) + // OG Not included (because its clear) } else { // Just generate as clear @@ -855,9 +765,7 @@ public class StatHistory { } // Validate non null - if (sData == null) { - return null; - } + if (sData == null) { return null; } // Can now generate stat history StatHistory sHistory = new StatHistory(iSource, stat, sData); @@ -936,7 +844,7 @@ public class StatHistory { } } //endregion - + //region Modifier History if (modEncode != null) { @@ -994,8 +902,7 @@ public class StatHistory { *

* Will be null if some error happens */ - @Nullable - public static StatHistory fromNBTString(@NotNull MMOItem iSource, @NotNull String codedJson) { + @Nullable public static StatHistory fromNBTString(@NotNull MMOItem iSource, @NotNull String codedJson) { // Attempt try { @@ -1030,43 +937,40 @@ public class StatHistory { // Stat must be the same if (other.getItemStat().getNBTPath().equals(getItemStat().getNBTPath())) { - //UPDT//MMOItems.log(" \u00a72>\u00a76> \u00a77History Stat Matches"); + //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()); + //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)); - } + registerGemstoneData(exUID, other.getGemstoneData(exUID)); } // Register externals - for (StatData ex : other.getExternalData()) { - registerExternalData((ex)); - } + for (StatData ex : other.getExternalData()) { registerExternalData((ex)); } // Register modifiers for (UUID exUID : other.getAllModifiers()) { //noinspection ConstantConditions - registerModifierBonus(exUID, other.getModifiersBonus(exUID)); - } + 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(); + //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(); } } /** * Clones this history but linked to another MMOItem. - *

+ * * It does not put it into the MMOItem, you must do that yourself. * + * @see MMOItem#setStatHistory(ItemStat, StatHistory) + * * @param clonedMMOItem Usually this is called when you are cloning the MMOItem itself, * this is a reference to the new one. - * @see MMOItem#setStatHistory(ItemStat, StatHistory) */ public StatHistory clone(@NotNull MMOItem clonedMMOItem) { @@ -1075,14 +979,10 @@ public class StatHistory { // Add all for (UUID uid : getAllGemstones()) { - if (uid == null) { - continue; - } + if (uid == null) { continue; } StatData gem = getGemstoneData(uid); - if (!(gem instanceof Mergeable)) { - continue; - } + if (!(gem instanceof Mergeable)) { continue; } // Clone res.registerGemstoneData(uid, ((Mergeable) gem).cloneData()); @@ -1090,25 +990,18 @@ public class StatHistory { // Add all for (StatData ex : getExternalData()) { - if (!(ex instanceof Mergeable)) { - continue; - } + if (!(ex instanceof Mergeable)) { continue; } // Clone - res.registerExternalData(((Mergeable) ex).cloneData()); - } + res.registerExternalData(((Mergeable) ex).cloneData()); } // Clone for (UUID uid : getAllModifiers()) { - if (uid == null) { - continue; - } + if (uid == null) { continue; } StatData mod = getModifiersBonus(uid); - if (!(mod instanceof Mergeable)) { - continue; - } + if (!(mod instanceof Mergeable)) { continue; } // Clone res.registerModifierBonus(uid, ((Mergeable) mod).cloneData()); @@ -1118,4 +1011,46 @@ 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"; + + + /** + * Logs into the console. Dev Mehtod + */ + 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);} + } + } }