diff --git a/Changelog.txt b/Changelog.txt index de25d1179..139db837b 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,3 +1,11 @@ +Version 2.1.143 + mcMMO now tracks super ability boosted items through item metadata + mcMMO no longer relies on lore to tell if an item has been modified by a super ability + + NOTES: + The item tracking on 1.14+ is persistent (up until now its been temporary) + Lore still gets added and removed from the item, this is sort of a failsafe. It can be considered optional. + Version 2.1.142 Iron Arm Style renamed to Steel Arm Style Steel Arm Style now scales over 20 ranks instead of 5 diff --git a/pom.xml b/pom.xml index a4aa7842b..402e8a0c7 100755 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 com.gmail.nossr50.mcMMO mcMMO - 2.1.142 + 2.1.143-SNAPSHOT mcMMO https://github.com/mcMMO-Dev/mcMMO diff --git a/src/main/java/com/gmail/nossr50/datatypes/meta/SuperAbilityToolMeta.java b/src/main/java/com/gmail/nossr50/datatypes/meta/SuperAbilityToolMeta.java new file mode 100644 index 000000000..b66f8dfef --- /dev/null +++ b/src/main/java/com/gmail/nossr50/datatypes/meta/SuperAbilityToolMeta.java @@ -0,0 +1,14 @@ +package com.gmail.nossr50.datatypes.meta; + +import com.gmail.nossr50.mcMMO; +import org.bukkit.metadata.FixedMetadataValue; + +/** + * Stores the original dig speed of a tool, also marks the tool as boosted by super abilities + */ +public class SuperAbilityToolMeta extends FixedMetadataValue { + + public SuperAbilityToolMeta(int value, mcMMO plugin) { + super(plugin, value); + } +} diff --git a/src/main/java/com/gmail/nossr50/listeners/InventoryListener.java b/src/main/java/com/gmail/nossr50/listeners/InventoryListener.java index 0052f1644..6c0ac6a0a 100644 --- a/src/main/java/com/gmail/nossr50/listeners/InventoryListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/InventoryListener.java @@ -414,6 +414,7 @@ public class InventoryListener implements Listener { ItemStack result = event.getRecipe().getResult(); + //TODO: what is the point of this if (!ItemUtils.isMcMMOItem(result)) { return; } diff --git a/src/main/java/com/gmail/nossr50/util/ItemUtils.java b/src/main/java/com/gmail/nossr50/util/ItemUtils.java index f7dea6a38..39720b038 100644 --- a/src/main/java/com/gmail/nossr50/util/ItemUtils.java +++ b/src/main/java/com/gmail/nossr50/util/ItemUtils.java @@ -1,17 +1,22 @@ package com.gmail.nossr50.util; +import com.gmail.nossr50.config.AdvancedConfig; import com.gmail.nossr50.config.Config; import com.gmail.nossr50.config.party.ItemWeightConfig; import com.gmail.nossr50.locale.LocaleLoader; import com.gmail.nossr50.mcMMO; import org.bukkit.ChatColor; import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; import org.bukkit.inventory.FurnaceRecipe; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.Recipe; import org.bukkit.inventory.meta.ItemMeta; +import java.util.ArrayList; +import java.util.List; + public final class ItemUtils { private ItemUtils() {} @@ -479,4 +484,45 @@ public final class ItemUtils { return itemMeta.hasDisplayName() && itemMeta.getDisplayName().equals(ChatColor.GOLD + LocaleLoader.getString("Item.ChimaeraWing.Name")); } + + public static void addAbilityLore(ItemStack itemStack) { + ItemMeta itemMeta = itemStack.getItemMeta(); + List itemLore = new ArrayList<>(); + + if(itemMeta == null) + return; + + if (itemMeta.hasLore()) { + itemLore = itemMeta.getLore(); + } + + itemLore.add("mcMMO Ability Tool"); + + itemMeta.setLore(itemLore); + itemStack.setItemMeta(itemMeta); + } + + public static void removeAbilityLore(ItemStack itemStack) { + ItemMeta itemMeta = itemStack.getItemMeta(); + + if(itemMeta == null) + return; + + if (itemMeta.hasLore()) { + List itemLore = itemMeta.getLore(); + + if(itemLore == null) + return; + + if (itemLore.remove("mcMMO Ability Tool")) { + itemMeta.setLore(itemLore); + itemStack.setItemMeta(itemMeta); + } + } + } + + public static void addDigSpeedToItem(ItemStack itemStack, int existingEnchantLevel) { + ItemMeta itemMeta = itemStack.getItemMeta(); + itemMeta.addEnchant(Enchantment.DIG_SPEED, existingEnchantLevel + AdvancedConfig.getInstance().getEnchantBuff(), true); + } } diff --git a/src/main/java/com/gmail/nossr50/util/compat/layers/persistentdata/AbstractPersistentDataLayer.java b/src/main/java/com/gmail/nossr50/util/compat/layers/persistentdata/AbstractPersistentDataLayer.java index 0cd936c2d..815c6c5b1 100644 --- a/src/main/java/com/gmail/nossr50/util/compat/layers/persistentdata/AbstractPersistentDataLayer.java +++ b/src/main/java/com/gmail/nossr50/util/compat/layers/persistentdata/AbstractPersistentDataLayer.java @@ -2,6 +2,8 @@ package com.gmail.nossr50.util.compat.layers.persistentdata; import com.gmail.nossr50.util.compat.layers.AbstractCompatibilityLayer; import org.bukkit.block.Furnace; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.Nullable; import java.util.UUID; @@ -16,4 +18,12 @@ public abstract class AbstractPersistentDataLayer extends AbstractCompatibilityL public abstract void setFurnaceOwner(Furnace furnace, UUID uuid); + public abstract void setSuperAbilityBoostedItem(ItemStack itemStack, int originalDigSpeed); + + public abstract boolean isSuperAbilityBoosted(ItemMeta itemMeta); + + public abstract int getSuperAbilityToolOriginalDigSpeed(ItemMeta itemMeta); + + public abstract void removeBonusDigSpeedOnSuperAbilityTool(ItemStack itemStack); + } diff --git a/src/main/java/com/gmail/nossr50/util/compat/layers/persistentdata/SpigotPersistentDataLayer.java b/src/main/java/com/gmail/nossr50/util/compat/layers/persistentdata/SpigotPersistentDataLayer.java index 87727ad42..760b074ad 100644 --- a/src/main/java/com/gmail/nossr50/util/compat/layers/persistentdata/SpigotPersistentDataLayer.java +++ b/src/main/java/com/gmail/nossr50/util/compat/layers/persistentdata/SpigotPersistentDataLayer.java @@ -3,6 +3,9 @@ package com.gmail.nossr50.util.compat.layers.persistentdata; import com.gmail.nossr50.mcMMO; import org.bukkit.NamespacedKey; import org.bukkit.block.Furnace; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataHolder; import org.bukkit.persistence.PersistentDataType; @@ -13,8 +16,17 @@ import java.util.UUID; public class SpigotPersistentDataLayer extends AbstractPersistentDataLayer { + /* + * Don't modify these keys + */ + public static final String FURNACE_UUID_MOST_SIG = "furnace_uuid_most_sig"; + public static final String FURNACE_UUID_LEAST_SIG = "furnace_uuid_least_sig"; + public static final String SUPER_ABILITY_BOOSTED = "super_ability_boosted"; + private NamespacedKey furnaceOwner_MostSig_Key; private NamespacedKey furnaceOwner_LeastSig_Key; + private NamespacedKey superAbilityBoosted; + @Override public boolean initializeLayer() { @@ -23,8 +35,9 @@ public class SpigotPersistentDataLayer extends AbstractPersistentDataLayer { } private void initNamespacedKeys() { - furnaceOwner_MostSig_Key = getNamespacedKey("furnace_uuid_most_sig"); - furnaceOwner_LeastSig_Key = getNamespacedKey("furnace_uuid_least_sig"); + furnaceOwner_MostSig_Key = getNamespacedKey(FURNACE_UUID_MOST_SIG); + furnaceOwner_LeastSig_Key = getNamespacedKey(FURNACE_UUID_LEAST_SIG); + superAbilityBoosted = getNamespacedKey(SUPER_ABILITY_BOOSTED); } @NotNull @@ -57,4 +70,62 @@ public class SpigotPersistentDataLayer extends AbstractPersistentDataLayer { furnace.update(); } + + @Override + public void setSuperAbilityBoostedItem(ItemStack itemStack, int originalDigSpeed) { + ItemMeta itemMeta = itemStack.getItemMeta(); + PersistentDataContainer dataContainer = ((PersistentDataHolder) itemMeta).getPersistentDataContainer(); + + dataContainer.set(superAbilityBoosted, PersistentDataType.INTEGER, originalDigSpeed); + + itemStack.setItemMeta(itemMeta); + } + + @Override + public boolean isSuperAbilityBoosted(@NotNull ItemMeta itemMeta) { + //Get container from entity + PersistentDataContainer dataContainer = ((PersistentDataHolder) itemMeta).getPersistentDataContainer(); + + //If this value isn't null, then the tool can be considered dig speed boosted + Integer boostValue = dataContainer.get(superAbilityBoosted, PersistentDataType.INTEGER); + + return boostValue != null; + } + + @Override + public int getSuperAbilityToolOriginalDigSpeed(@NotNull ItemMeta itemMeta) { + //Get container from entity + PersistentDataContainer dataContainer = ((PersistentDataHolder) itemMeta).getPersistentDataContainer(); + + if(dataContainer.get(superAbilityBoosted, PersistentDataType.INTEGER) == null) { + mcMMO.p.getLogger().severe("Value should never be null for a boosted item"); + return 0; + } else { + //Too lazy to make a custom data type for this stuff + Integer boostValue = dataContainer.get(superAbilityBoosted, PersistentDataType.INTEGER); + return Math.max(boostValue, 0); + } + } + + @Override + public void removeBonusDigSpeedOnSuperAbilityTool(@NotNull ItemStack itemStack) { + ItemMeta itemMeta = itemStack.getItemMeta(); + + //TODO: can be optimized + int originalSpeed = getSuperAbilityToolOriginalDigSpeed(itemMeta); + + if(itemMeta.hasEnchant(Enchantment.DIG_SPEED)) { + itemMeta.removeEnchant(Enchantment.DIG_SPEED); + } + + if(originalSpeed > 0) { + itemMeta.addEnchant(Enchantment.DIG_SPEED, originalSpeed, true); + } + + PersistentDataContainer dataContainer = ((PersistentDataHolder) itemMeta).getPersistentDataContainer(); + dataContainer.remove(superAbilityBoosted); //Remove persistent data + + //TODO: needed? + itemStack.setItemMeta(itemMeta); + } } diff --git a/src/main/java/com/gmail/nossr50/util/compat/layers/persistentdata/SpigotTemporaryDataLayer.java b/src/main/java/com/gmail/nossr50/util/compat/layers/persistentdata/SpigotTemporaryDataLayer.java index a912520b4..13e845d4e 100644 --- a/src/main/java/com/gmail/nossr50/util/compat/layers/persistentdata/SpigotTemporaryDataLayer.java +++ b/src/main/java/com/gmail/nossr50/util/compat/layers/persistentdata/SpigotTemporaryDataLayer.java @@ -1,9 +1,15 @@ package com.gmail.nossr50.util.compat.layers.persistentdata; +import com.gmail.nossr50.config.AdvancedConfig; +import com.gmail.nossr50.datatypes.meta.SuperAbilityToolMeta; import com.gmail.nossr50.datatypes.meta.UUIDMeta; import com.gmail.nossr50.mcMMO; import org.bukkit.block.Furnace; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.metadata.Metadatable; +import org.jetbrains.annotations.NotNull; import java.util.UUID; @@ -13,6 +19,7 @@ import java.util.UUID; public class SpigotTemporaryDataLayer extends AbstractPersistentDataLayer { private final String FURNACE_OWNER_METADATA_KEY = "mcMMO_furnace_owner"; + private final String ABILITY_TOOL_METADATA_KEY = "mcMMO_super_ability_tool"; @Override public boolean initializeLayer() { @@ -41,4 +48,51 @@ public class SpigotTemporaryDataLayer extends AbstractPersistentDataLayer { metadatable.setMetadata(FURNACE_OWNER_METADATA_KEY, new UUIDMeta(mcMMO.p, uuid)); } + + @Override + public void setSuperAbilityBoostedItem(ItemStack itemStack, int originalDigSpeed) { + ItemMeta itemMeta = itemStack.getItemMeta(); + Metadatable metadatable = (Metadatable) itemMeta; + metadatable.setMetadata(ABILITY_TOOL_METADATA_KEY, new SuperAbilityToolMeta(originalDigSpeed, mcMMO.p)); + + //TODO: needed? + itemStack.setItemMeta(itemMeta); + } + + @Override + public boolean isSuperAbilityBoosted(@NotNull ItemMeta itemMeta) { + Metadatable metadatable = (Metadatable) itemMeta; + return metadatable.getMetadata(ABILITY_TOOL_METADATA_KEY).size() > 0; + } + + @Override + public int getSuperAbilityToolOriginalDigSpeed(@NotNull ItemMeta itemMeta) { + Metadatable metadatable = (Metadatable) itemMeta; + + if(metadatable.getMetadata(ABILITY_TOOL_METADATA_KEY).size() > 0) { + SuperAbilityToolMeta toolMeta = (SuperAbilityToolMeta) metadatable.getMetadata(ABILITY_TOOL_METADATA_KEY).get(0); + return toolMeta.asInt(); + } else { +// mcMMO.p.getLogger().info("Original dig enchant speed could not be found on item! Most likely it was lost from a server restart."); + return 0; + } + } + + @Override + public void removeBonusDigSpeedOnSuperAbilityTool(@NotNull ItemStack itemStack) { + ItemMeta itemMeta = itemStack.getItemMeta(); + + if(itemMeta.hasEnchant(Enchantment.DIG_SPEED)) { + itemMeta.removeEnchant(Enchantment.DIG_SPEED); + } + + int originalSpeed = getSuperAbilityToolOriginalDigSpeed(itemMeta); + + if(originalSpeed > 0) { + itemMeta.addEnchant(Enchantment.DIG_SPEED, originalSpeed, true); + } + + //TODO: needed? + itemStack.setItemMeta(itemMeta); + } } diff --git a/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java b/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java index 35e0dca39..65f724f5d 100644 --- a/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java +++ b/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java @@ -15,6 +15,7 @@ import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.util.ItemUtils; import com.gmail.nossr50.util.Misc; import com.gmail.nossr50.util.StringUtils; +import com.gmail.nossr50.util.compat.layers.persistentdata.AbstractPersistentDataLayer; import com.gmail.nossr50.util.player.NotificationManager; import com.gmail.nossr50.util.player.UserManager; import org.bukkit.Bukkit; @@ -22,10 +23,7 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.Recipe; -import org.bukkit.inventory.ShapedRecipe; -import org.bukkit.inventory.ShapelessRecipe; +import org.bukkit.inventory.*; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; @@ -140,19 +138,15 @@ public class SkillUtils { return; } - int efficiencyLevel = heldItem.getEnchantmentLevel(Enchantment.DIG_SPEED); - ItemMeta itemMeta = heldItem.getItemMeta(); - List itemLore = new ArrayList<>(); + int originalDigSpeed = heldItem.getEnchantmentLevel(Enchantment.DIG_SPEED); - if (itemMeta.hasLore()) { - itemLore = itemMeta.getLore(); - } + //Add lore, add dig speed + ItemUtils.addAbilityLore(heldItem); //lore can be a secondary failsafe for 1.13 and below + ItemUtils.addDigSpeedToItem(heldItem, heldItem.getEnchantmentLevel(Enchantment.DIG_SPEED)); - itemLore.add("mcMMO Ability Tool"); - itemMeta.addEnchant(Enchantment.DIG_SPEED, efficiencyLevel + AdvancedConfig.getInstance().getEnchantBuff(), true); - - itemMeta.setLore(itemLore); - heldItem.setItemMeta(itemMeta); + //1.14+ will have persistent metadata for this item + AbstractPersistentDataLayer compatLayer = mcMMO.getCompatibilityManager().getPersistentDataLayer(); + compatLayer.setSuperAbilityBoostedItem(heldItem, originalDigSpeed); } else { int duration = 0; @@ -205,30 +199,19 @@ public class SkillUtils { } } - public static void removeAbilityBuff(ItemStack item) { - if (item == null || item.getType() == Material.AIR || (!ItemUtils.isPickaxe(item) && !ItemUtils.isShovel(item)) || !item.containsEnchantment(Enchantment.DIG_SPEED)) { + public static void removeAbilityBuff(ItemStack itemStack) { + if (itemStack == null || itemStack.getType() == Material.AIR) { return; } - ItemMeta itemMeta = item.getItemMeta(); + //Take the lore off + ItemUtils.removeAbilityLore(itemStack); - if (itemMeta.hasLore()) { - List itemLore = itemMeta.getLore(); + //1.14+ will have persistent metadata for this itemStack + AbstractPersistentDataLayer compatLayer = mcMMO.getCompatibilityManager().getPersistentDataLayer(); - if (itemLore.remove("mcMMO Ability Tool")) { - int efficiencyLevel = item.getEnchantmentLevel(Enchantment.DIG_SPEED); - - if (efficiencyLevel <= AdvancedConfig.getInstance().getEnchantBuff()) { - itemMeta.removeEnchant(Enchantment.DIG_SPEED); - } - else { - itemMeta.addEnchant(Enchantment.DIG_SPEED, efficiencyLevel - AdvancedConfig.getInstance().getEnchantBuff(), true); - } - - itemMeta.setLore(itemLore); - item.setItemMeta(itemMeta); - } - } + if(compatLayer.isSuperAbilityBoosted(itemStack.getItemMeta())) + compatLayer.removeBonusDigSpeedOnSuperAbilityTool(itemStack); } public static void handleDurabilityChange(ItemStack itemStack, int durabilityModifier) {