From 1d075b28e5452384be0f9b75c4ad8d1d88ad34b2 Mon Sep 17 00:00:00 2001 From: Gunging Date: Tue, 30 Mar 2021 02:50:11 -0500 Subject: [PATCH] **If you use the plugin PhatLoots** well this update is about better use of it! You can now go to your config and add, under item-revision: ```yml item-revision: phat-loots: display-name: true lore: true enchantments: true soulbound: true upgrades: true gemstones: true modifications: true external-sh: true ``` Which will update your PhatLoot items to the latest format in `/mmoitems browse` as they are generated for players. Since this will regenerate items, the *Unstackable* ItemStat now works with PhatLoots also ***If this is not added to the config, ** the default is that all options are false, and the items are completely regenerated and RNG-rerolled. --- pom.xml | 10 ++ .../java/net/Indyuce/mmoitems/MMOItems.java | 2 + .../Indyuce/mmoitems/api/ReforgeOptions.java | 33 +++- .../api/item/template/MMOItemTemplate.java | 3 +- .../mmoitems/api/util/MMOItemReforger.java | 163 ++++++++---------- .../mmoitems/ReloadCommandTreeNode.java | 2 + .../Indyuce/mmoitems/comp/PhatLootsHook.java | 72 ++++++++ .../mmoitems/listener/ItemListener.java | 7 +- .../mmoitems/manager/ConfigManager.java | 14 +- 9 files changed, 201 insertions(+), 105 deletions(-) create mode 100644 src/main/java/net/Indyuce/mmoitems/comp/PhatLootsHook.java diff --git a/pom.xml b/pom.xml index 3db97729..503a40ed 100644 --- a/pom.xml +++ b/pom.xml @@ -70,6 +70,10 @@ placeholderapi http://repo.extendedclip.com/content/repositories/placeholderapi/ + + jitpack.io + https://jitpack.io + @@ -139,6 +143,12 @@ system ${basedir}/lib/Iridescent.jar + + com.github.RednedEpic + PhatLoots + master-dev-build-79-g4ab7dd1-97 + provided + diff --git a/src/main/java/net/Indyuce/mmoitems/MMOItems.java b/src/main/java/net/Indyuce/mmoitems/MMOItems.java index 616cc176..df8a5510 100644 --- a/src/main/java/net/Indyuce/mmoitems/MMOItems.java +++ b/src/main/java/net/Indyuce/mmoitems/MMOItems.java @@ -191,6 +191,8 @@ public class MMOItems extends LuminePlugin { Bukkit.getPluginManager().registerEvents(new GuiListener(), this); Bukkit.getPluginManager().registerEvents(new ElementListener(), this); Bukkit.getPluginManager().registerEvents(new CustomBlockListener(), this); + if (Bukkit.getPluginManager().getPlugin("PhatLoots") != null) { + Bukkit.getPluginManager().registerEvents(new PhatLootsHook(), this); } MMOItemUIFilter.register(); Bukkit.getScheduler().runTaskTimer(this, () -> Bukkit.getOnlinePlayers().forEach(player -> PlayerData.get(player).updateStats()), 100, 20); diff --git a/src/main/java/net/Indyuce/mmoitems/api/ReforgeOptions.java b/src/main/java/net/Indyuce/mmoitems/api/ReforgeOptions.java index bd993d8a..7a1b83a3 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/ReforgeOptions.java +++ b/src/main/java/net/Indyuce/mmoitems/api/ReforgeOptions.java @@ -1,16 +1,23 @@ package net.Indyuce.mmoitems.api; +import net.Indyuce.mmoitems.MMOItems; import org.bukkit.configuration.ConfigurationSection; public class ReforgeOptions { private final boolean - keepName, - keepLore, - keepEnchantments, - keepUpgrades, - keepGemStones, - keepSoulbind, - keepExternalSH; + keepName; + private final boolean keepLore; + private final boolean keepEnchantments; + private final boolean keepUpgrades; + private final boolean keepGemStones; + private final boolean keepSoulbind; + private final boolean keepExternalSH; + + public boolean isRegenerate() { + return regenerate; + } + + private final boolean regenerate; public ReforgeOptions(ConfigurationSection config) { this.keepName = config.getBoolean("display-name"); @@ -20,6 +27,18 @@ public class ReforgeOptions { this.keepGemStones = config.getBoolean("gemstones"); this.keepSoulbind = config.getBoolean("soulbound"); this.keepExternalSH = config.getBoolean("external-sh", true); + this.regenerate = false; + } + + public ReforgeOptions(boolean keepName, boolean keepLore, boolean keepEnchantments, boolean keepUpgrades, boolean keepGemStones, boolean keepSoulbind, boolean keepExternalSH, boolean regenerate) { + this.keepName = keepName; + this.keepLore = keepLore; + this.keepEnchantments = keepEnchantments; + this.keepUpgrades = keepUpgrades; + this.keepGemStones = keepGemStones; + this.keepSoulbind = keepSoulbind; + this.keepExternalSH = keepExternalSH; + this.regenerate = regenerate; } /** diff --git a/src/main/java/net/Indyuce/mmoitems/api/item/template/MMOItemTemplate.java b/src/main/java/net/Indyuce/mmoitems/api/item/template/MMOItemTemplate.java index f20ee21c..7f0174dc 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/item/template/MMOItemTemplate.java +++ b/src/main/java/net/Indyuce/mmoitems/api/item/template/MMOItemTemplate.java @@ -17,6 +17,7 @@ import net.Indyuce.mmoitems.stat.data.random.RandomStatData; import net.Indyuce.mmoitems.stat.type.ItemStat; import org.apache.commons.lang.Validate; import org.bukkit.configuration.ConfigurationSection; +import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; import java.util.*; @@ -150,7 +151,7 @@ public class MMOItemTemplate extends PostLoadObject implements ItemReference { * matter when rolling for the 'item level' * @return Item builder with random level and tier? */ - public MMOItemBuilder newBuilder(RPGPlayer player) { + public MMOItemBuilder newBuilder(@NotNull RPGPlayer player) { int itemLevel = hasOption(TemplateOption.LEVEL_ITEM) ? MMOItems.plugin.getTemplates().rollLevel(player.getLevel()) : 0; ItemTier itemTier = hasOption(TemplateOption.TIERED) ? MMOItems.plugin.getTemplates().rollTier() : null; return new MMOItemBuilder(this, itemLevel, itemTier); diff --git a/src/main/java/net/Indyuce/mmoitems/api/util/MMOItemReforger.java b/src/main/java/net/Indyuce/mmoitems/api/util/MMOItemReforger.java index 2794bf88..e044c646 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/util/MMOItemReforger.java +++ b/src/main/java/net/Indyuce/mmoitems/api/util/MMOItemReforger.java @@ -51,12 +51,10 @@ public class MMOItemReforger { //region Config Values static int autoSoulboundLevel = 1; static int defaultItemLevel = -32767; - static boolean rerollWhenUpdated = false; static boolean keepTiersWhenReroll = true; public static void reload() { autoSoulboundLevel = MMOItems.plugin.getConfig().getInt("soulbound.auto-bind.level", 1); - rerollWhenUpdated = MMOItems.plugin.getConfig().getBoolean("item-revision.reroll-when-updated", false); defaultItemLevel = MMOItems.plugin.getConfig().getInt("item-revision.default-item-level", -32767); keepTiersWhenReroll = MMOItems.plugin.getConfig().getBoolean("item-revision.keep-tiers"); } @@ -161,15 +159,9 @@ public class MMOItemReforger { * * @see RevisionID */ + @SuppressWarnings("ConstantConditions") public void update(@Nullable RPGPlayer player, @NotNull ReforgeOptions options) { - - // Should it re-roll RNG? - if (rerollWhenUpdated) { - - // Reroute to Reforge - reforge(player, options); - return; - } + if (options.isRegenerate()) { regenerate(player); return; } /* * Has to store every stat into itemData, then check each stat of @@ -353,49 +345,7 @@ public class MMOItemReforger { /* * Generate fresh MMOItem, with stats that will be set if the chance is too low */ - int determinedItemLevel; - if (player == null) { - - // Get default Item Level - final int iLevel = defaultItemLevel; - - // What level with the regenerated item will be hmmmm..... - determinedItemLevel = - - // No default level specified? - (iLevel == -32767) ? - - // Does the item have level? - (mmoItem.hasData(ItemStats.ITEM_LEVEL) ? (int) ((DoubleData) mmoItem.getData(ItemStats.ITEM_LEVEL)).getValue() : 0 ) - - // Default level was specified, use that. - : iLevel; - - - // Identify tier. - ItemTier tier = - - // Does the item have a tier, and it should keep it? - (keepTiersWhenReroll && mmoItem.hasData(ItemStats.TIER)) ? - - // The tier will be the current tier - MMOItems.plugin.getTiers().get(mmoItem.getData(ItemStats.TIER).toString()) - - // The item either has no tier, or shouldn't keep it. Null - : null; - - // Build it again (Reroll RNG) - mmoItem = template.newBuilder(determinedItemLevel, tier).build(); - - // No player provided, use defaults. - } else { - - // What level with the regenerated item will be hmmmm..... - determinedItemLevel = (mmoItem.hasData(ItemStats.ITEM_LEVEL) ? (int) ((DoubleData) mmoItem.getData(ItemStats.ITEM_LEVEL)).getValue() : 0 ); - - // Build it again (Reroll RNG) - mmoItem = template.newBuilder(player).build(); - } + int determinedItemLevel = regenerate(player, template); //UPD//MMOItems.log("Determined Level: \u00a7e" + determinedItemLevel); /* @@ -581,6 +531,72 @@ public class MMOItemReforger { } } + void regenerate(@Nullable RPGPlayer p) { + + loadVolatileMMOItem(); + MMOItemTemplate template = MMOItems.plugin.getTemplates().getTemplate(mmoItem.getType(), mmoItem.getId()); ItemMeta meta = nbtItem.getItem().getItemMeta(); + //noinspection ConstantConditions + Validate.isTrue(meta != null, FriendlyFeedbackProvider.quickForConsole(FFPMMOItems.get(), "Invalid item meta prevented $f{0}$b from updating.", template.getType().toString() + " " + template.getId())); + + //UPD//MMOItems.log("\u00a79*\u00a77 Regenerating... \u00a7d" + template.getId() + " " + template.getType()); + + if (p != null) { + + mmoItem = template.newBuilder(p).build(); + } else { + + mmoItem = template.newBuilder((mmoItem.hasData(ItemStats.ITEM_LEVEL) ? (int) ((DoubleData) mmoItem.getData(ItemStats.ITEM_LEVEL)).getValue() : 0 ), null).build(); + } + } + int regenerate(@Nullable RPGPlayer player, @NotNull MMOItemTemplate template) { + + int determinedItemLevel; + if (player == null) { + + // Get default Item Level + final int iLevel = defaultItemLevel; + + // What level with the regenerated item will be hmmmm..... + determinedItemLevel = + + // No default level specified? + (iLevel == -32767) ? + + // Does the item have level? + (mmoItem.hasData(ItemStats.ITEM_LEVEL) ? (int) ((DoubleData) mmoItem.getData(ItemStats.ITEM_LEVEL)).getValue() : 0 ) + + // Default level was specified, use that. + : iLevel; + + + // Identify tier. + ItemTier tier = + + // Does the item have a tier, and it should keep it? + (keepTiersWhenReroll && mmoItem.hasData(ItemStats.TIER)) ? + + // The tier will be the current tier + MMOItems.plugin.getTiers().get(mmoItem.getData(ItemStats.TIER).toString()) + + // The item either has no tier, or shouldn't keep it. Null + : null; + + // Build it again (Reroll RNG) + mmoItem = template.newBuilder(determinedItemLevel, tier).build(); + + // No player provided, use defaults. + } else { + + // What level with the regenerated item will be hmmmm..... + determinedItemLevel = (mmoItem.hasData(ItemStats.ITEM_LEVEL) ? (int) ((DoubleData) mmoItem.getData(ItemStats.ITEM_LEVEL)).getValue() : 0 ); + + // Build it again (Reroll RNG) + mmoItem = template.newBuilder(player).build(); + } + + return determinedItemLevel; + } + /** * Generates a new item of the same Type-ID and transfers the data * from the old one following the options. @@ -609,6 +625,7 @@ public class MMOItemReforger { * or default values if needed. */ public void reforge(@Nullable RPGPlayer player, @NotNull ReforgeOptions options) { + if (options.isRegenerate()) { regenerate(player); return; } // Initialize as Volatile, find source template. GemStones require a Live MMOItem though (to correctly load all Stat Histories and sh) if (!options.shouldKeepGemStones() && !options.shouldKeepExternalSH()) { loadVolatileMMOItem(); } else { loadLiveMMOItem(); } @@ -771,45 +788,7 @@ public class MMOItemReforger { cachedSoulbound = mmoItem.getData(ItemStats.SOULBOUND); } - if (player == null) { - - // Get default Item Level - final int iLevel = defaultItemLevel; - - // What level with the regenerated item will be hmmmm..... - int level = - - // No default level specified? - (iLevel == -32767) ? - - // Does the item have level? - (mmoItem.hasData(ItemStats.ITEM_LEVEL) ? (int) ((DoubleData) mmoItem.getData(ItemStats.ITEM_LEVEL)).getValue() : 0 ) - - // Default level was specified, use that. - : iLevel; - - - // Identify tier. - ItemTier tier = - - // Does the item have a tier, and it should keep it? - (keepTiersWhenReroll && mmoItem.hasData(ItemStats.TIER)) ? - - // The tier will be the current tier - MMOItems.plugin.getTiers().get(mmoItem.getData(ItemStats.TIER).toString()) - - // The item either has no tier, or shouldn't keep it. Null - : null; - - // Build it again (Reroll RNG) - mmoItem = template.newBuilder(level, tier).build(); - - // No player provided, use defaults. - } else { - - // Build it again (Reroll RNG) - mmoItem = template.newBuilder(player).build(); - } + regenerate(player, template); /* * todo We cannot yet assume (for a few months) that the Original Enchantment Data diff --git a/src/main/java/net/Indyuce/mmoitems/command/mmoitems/ReloadCommandTreeNode.java b/src/main/java/net/Indyuce/mmoitems/command/mmoitems/ReloadCommandTreeNode.java index 9c1a34f2..911cc7dd 100644 --- a/src/main/java/net/Indyuce/mmoitems/command/mmoitems/ReloadCommandTreeNode.java +++ b/src/main/java/net/Indyuce/mmoitems/command/mmoitems/ReloadCommandTreeNode.java @@ -2,6 +2,7 @@ package net.Indyuce.mmoitems.command.mmoitems; import io.lumine.mythic.lib.mmolibcommands.api.CommandTreeNode; import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.api.util.MMOItemReforger; import net.Indyuce.mmoitems.api.util.NumericStatFormula; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; @@ -69,6 +70,7 @@ public class ReloadCommandTreeNode extends CommandTreeNode { // *This one is not implementing Reloadable NumericStatFormula.reload(); + MMOItemReforger.reload(); } public void reloadRecipes(CommandSender sender) { diff --git a/src/main/java/net/Indyuce/mmoitems/comp/PhatLootsHook.java b/src/main/java/net/Indyuce/mmoitems/comp/PhatLootsHook.java new file mode 100644 index 00000000..4471a358 --- /dev/null +++ b/src/main/java/net/Indyuce/mmoitems/comp/PhatLootsHook.java @@ -0,0 +1,72 @@ +package net.Indyuce.mmoitems.comp; + +import com.codisimus.plugins.phatloots.events.LootEvent; +import com.codisimus.plugins.phatloots.events.MobDropLootEvent; +import com.codisimus.plugins.phatloots.events.PhatLootsEvent; +import com.codisimus.plugins.phatloots.events.PlayerLootEvent; +import io.lumine.mythic.lib.api.item.NBTItem; +import io.lumine.mythic.lib.api.util.ui.SilentNumbers; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.api.player.RPGPlayer; +import net.Indyuce.mmoitems.api.util.MMOItemReforger; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.ArrayList; + +/** + * Its absolute pain that PhatLoots keeps giving outdated + * MMOItems that don't stack, so that now MMOItems shall support fixing those items + * as they are generated. + */ +public class PhatLootsHook implements Listener { + + + @EventHandler + public void OnLootBeLooted(MobDropLootEvent event) { handle(event);} + + @EventHandler + public void OnLootBeLooted(PlayerLootEvent event) { handle(event);} + + public void handle(LootEvent event) { + + // Fix stacks + for (ItemStack itm : event.getItemList()) { + //UPD//MMOItems.log("\u00a79*\u00a77 Looted " + SilentNumbers.getItemName(itm)); + + // Skip + if (SilentNumbers.isAir(itm)) { + //UPD//MMOItems.log("\u00a71*\u00a78 Air"); + continue; } + + // NBT-Ize + NBTItem loot = NBTItem.get(itm); + + // Not MMOItems I sleep + if (!loot.hasType()) { + //UPD//MMOItems.log("\u00a71*\u00a78 Vanilla"); + continue; } + + // All right update the bitch + MMOItemReforger mod = new MMOItemReforger(loot); + mod.update((RPGPlayer) null, MMOItems.plugin.getLanguage().phatLootsOptions); + + // Changes? + if (mod.hasChanges()) { + + // LEts go + ItemStack gen = mod.toStack(); + gen.setAmount(itm.getAmount()); + ItemMeta genMeta = gen.getItemMeta(); + //UPD//MMOItems.log("\u00a73+*\u00a77 Output " + SilentNumbers.getItemName(gen)); + + // Completely Replace + itm.setType(gen.getType()); + itm.setItemMeta(genMeta); + itm.setData(gen.getData()); } + + } } +} diff --git a/src/main/java/net/Indyuce/mmoitems/listener/ItemListener.java b/src/main/java/net/Indyuce/mmoitems/listener/ItemListener.java index c19ed610..e15b5729 100644 --- a/src/main/java/net/Indyuce/mmoitems/listener/ItemListener.java +++ b/src/main/java/net/Indyuce/mmoitems/listener/ItemListener.java @@ -83,7 +83,12 @@ public class ItemListener implements Listener { // Should this item be updated (via the updater) if (shouldUpdate(nbt, type)) { - mod.update(MMOItems.plugin.getLanguage().rerollOnItemUpdate ? player : null, MMOItems.plugin.getLanguage().revisionOptions); } + + // Reforge vs Update bro + if (MMOItems.plugin.getLanguage().rerollOnItemUpdate) { + mod.reforge(player, MMOItems.plugin.getLanguage().revisionOptions); } else { + mod.update(player, MMOItems.plugin.getLanguage().revisionOptions); } + } // Should this item be soulbound? if (shouldSoulbind(nbt, type)) { mod.applySoulbound(player); } diff --git a/src/main/java/net/Indyuce/mmoitems/manager/ConfigManager.java b/src/main/java/net/Indyuce/mmoitems/manager/ConfigManager.java index 12a8b828..7545674d 100644 --- a/src/main/java/net/Indyuce/mmoitems/manager/ConfigManager.java +++ b/src/main/java/net/Indyuce/mmoitems/manager/ConfigManager.java @@ -43,7 +43,7 @@ public class ConfigManager implements Reloadable { public DecimalFormat healIndicatorDecimalFormat, damageIndicatorDecimalFormat; public double dodgeKnockbackForce, soulboundBaseDamage, soulboundPerLvlDamage, levelSpread; public NumericStatFormula defaultItemCapacity; - public ReforgeOptions revisionOptions; + public ReforgeOptions revisionOptions, phatLootsOptions; /** DE-TAREAS: Implement reward system for good users? */ @SuppressWarnings("unused") @@ -205,8 +205,11 @@ public class ConfigManager implements Reloadable { abilityPlayerDamage = MMOItems.plugin.getConfig().getBoolean("ability-player-damage"); healIndicatorFormat = MythicLib.plugin.parseColors(MMOItems.plugin.getConfig().getString("game-indicators.heal.format")); damageIndicatorFormat = MythicLib.plugin.parseColors(MMOItems.plugin.getConfig().getString("game-indicators.damage.format")); - healIndicatorDecimalFormat = new DecimalFormat(MMOItems.plugin.getConfig().getString("game-indicators.heal.decimal-format")); - damageIndicatorDecimalFormat = new DecimalFormat(MMOItems.plugin.getConfig().getString("game-indicators.damage.decimal-format")); + + String healDecimal = MMOItems.plugin.getConfig().getString("game-indicators.heal.decimal-format"); + String harmDecimal = MMOItems.plugin.getConfig().getString("game-indicators.damage.decimal-format"); + healIndicatorDecimalFormat = healDecimal != null ? new DecimalFormat(healDecimal) : new DecimalFormat("0.#"); + damageIndicatorDecimalFormat = harmDecimal != null ? new DecimalFormat(harmDecimal) : new DecimalFormat("0.#"); abilitySplitter = getStatFormat("ability-splitter"); dodgeKnockbackForce = MMOItems.plugin.getConfig().getDouble("mitigation.dodge.knockback.force"); dodgeKnockbackEnabled = MMOItems.plugin.getConfig().getBoolean("mitigation.dodge.knockback.enabled"); @@ -217,7 +220,10 @@ public class ConfigManager implements Reloadable { rerollOnItemUpdate = MMOItems.plugin.getConfig().getBoolean("item-revision.reroll-when-updated"); levelSpread = MMOItems.plugin.getConfig().getDouble("item-level-spread"); - revisionOptions = new ReforgeOptions(MMOItems.plugin.getConfig().getConfigurationSection("item-revision.keep-data")); + ConfigurationSection keepData = MMOItems.plugin.getConfig().getConfigurationSection("item-revision.keep-data"); + ConfigurationSection phatLoots = MMOItems.plugin.getConfig().getConfigurationSection("item-revision.phat-loots"); + revisionOptions = keepData != null ? new ReforgeOptions(keepData) : new ReforgeOptions(false, false, false, false, false, false, false, true); + phatLootsOptions = phatLoots != null ? new ReforgeOptions(phatLoots) : new ReforgeOptions(false, false, false, false, false, false, false, true); try { defaultItemCapacity = new NumericStatFormula(MMOItems.plugin.getConfig().getConfigurationSection("default-item-capacity"));