Allow upgrading diamond AE to netherite
- Added config option to make it possible to upgrade diamond AEs to netherite ones. - Refactored code a bit to avoid duplicating stuff between the crafting/upgrading classes.
This commit is contained in:
		@@ -6,7 +6,8 @@ import nl.pim16aap2.armoredElytra.handlers.EventHandlers;
 | 
			
		||||
import nl.pim16aap2.armoredElytra.handlers.FlyDurabilityHandler;
 | 
			
		||||
import nl.pim16aap2.armoredElytra.handlers.ItemDropListener;
 | 
			
		||||
import nl.pim16aap2.armoredElytra.handlers.LoginHandler;
 | 
			
		||||
import nl.pim16aap2.armoredElytra.handlers.SmithingTableHandler;
 | 
			
		||||
import nl.pim16aap2.armoredElytra.handlers.NetheriteUpgradeListener;
 | 
			
		||||
import nl.pim16aap2.armoredElytra.handlers.SmithingTableCraftHandler;
 | 
			
		||||
import nl.pim16aap2.armoredElytra.handlers.Uninstaller;
 | 
			
		||||
import nl.pim16aap2.armoredElytra.nbtEditor.INBTEditor;
 | 
			
		||||
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
 | 
			
		||||
@@ -105,8 +106,10 @@ public class ArmoredElytra extends JavaPlugin implements Listener
 | 
			
		||||
                myLogger(Level.INFO, "Durability penalty for flying enabled!");
 | 
			
		||||
 | 
			
		||||
            final Listener creationListener = config.craftingInSmithingTable() ?
 | 
			
		||||
                                              new SmithingTableHandler(this) : new AnvilHandler(this);
 | 
			
		||||
                                              new SmithingTableCraftHandler(this) : new AnvilHandler(this);
 | 
			
		||||
            Bukkit.getPluginManager().registerEvents(creationListener, this);
 | 
			
		||||
            if (config.allowUpgradeToNetherite())
 | 
			
		||||
                Bukkit.getPluginManager().registerEvents(new NetheriteUpgradeListener(this), this);
 | 
			
		||||
 | 
			
		||||
            if (config.dropNetheriteAsChestplate())
 | 
			
		||||
                Bukkit.getPluginManager().registerEvents(new ItemDropListener(this), this);
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,58 @@
 | 
			
		||||
package nl.pim16aap2.armoredElytra.handlers;
 | 
			
		||||
 | 
			
		||||
import nl.pim16aap2.armoredElytra.ArmoredElytra;
 | 
			
		||||
import nl.pim16aap2.armoredElytra.util.ArmorTier;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.event.EventHandler;
 | 
			
		||||
import org.bukkit.event.inventory.InventoryClickEvent;
 | 
			
		||||
import org.bukkit.event.inventory.PrepareSmithingEvent;
 | 
			
		||||
import org.bukkit.inventory.ItemStack;
 | 
			
		||||
import org.bukkit.inventory.SmithingInventory;
 | 
			
		||||
 | 
			
		||||
public class NetheriteUpgradeListener extends SmithingTableListener
 | 
			
		||||
{
 | 
			
		||||
    public NetheriteUpgradeListener(final ArmoredElytra plugin)
 | 
			
		||||
    {
 | 
			
		||||
        super(plugin);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @EventHandler(ignoreCancelled = true)
 | 
			
		||||
    public void onSmithingTableUsage(final PrepareSmithingEvent event)
 | 
			
		||||
    {
 | 
			
		||||
        super.onSmithingTableUsage(event);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected ArmorTier getArmorTier(ItemStack itemStackA, ItemStack itemStackB)
 | 
			
		||||
    {
 | 
			
		||||
        if (itemStackA == null || itemStackB == null ||
 | 
			
		||||
            itemStackA.getType() != Material.ELYTRA ||
 | 
			
		||||
            plugin.getNbtEditor().getArmorTier(itemStackA) != ArmorTier.DIAMOND ||
 | 
			
		||||
            itemStackB.getType() != Material.NETHERITE_INGOT)
 | 
			
		||||
            return ArmorTier.NONE;
 | 
			
		||||
 | 
			
		||||
        // For some reason, adding multiple netherite ingots causes the view to not update properly.
 | 
			
		||||
        // The resulting armored elytra is hidden and the red cross indicates the combination is impossible.
 | 
			
		||||
        // But if you click on where the output was supposed to be, it DOES work for some reason.
 | 
			
		||||
        // It kinda works if you add a slight delay, but I don't really like that. Might revisit this later. CBA now.
 | 
			
		||||
        if (itemStackA.getAmount() != 1 || itemStackB.getAmount() != 1)
 | 
			
		||||
            return ArmorTier.NONE;
 | 
			
		||||
 | 
			
		||||
        return ArmorTier.NETHERITE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @EventHandler(ignoreCancelled = true)
 | 
			
		||||
    public void onInventoryClick(InventoryClickEvent event)
 | 
			
		||||
    {
 | 
			
		||||
        if (!isAESmithingTableEvent(event))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        // These casts may look unchecked, but it was checked by isSmithingTableEvent already.
 | 
			
		||||
        SmithingInventory smithingInventory = (SmithingInventory) event.getInventory();
 | 
			
		||||
        Player player = (Player) event.getWhoClicked();
 | 
			
		||||
 | 
			
		||||
        giveItemToPlayer(player, smithingInventory.getItem(2), event.isShiftClick());
 | 
			
		||||
        smithingInventory.clear();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,52 @@
 | 
			
		||||
package nl.pim16aap2.armoredElytra.handlers;
 | 
			
		||||
 | 
			
		||||
import nl.pim16aap2.armoredElytra.ArmoredElytra;
 | 
			
		||||
import nl.pim16aap2.armoredElytra.util.ArmorTier;
 | 
			
		||||
import nl.pim16aap2.armoredElytra.util.Util;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.event.EventHandler;
 | 
			
		||||
import org.bukkit.event.inventory.InventoryClickEvent;
 | 
			
		||||
import org.bukkit.event.inventory.PrepareSmithingEvent;
 | 
			
		||||
import org.bukkit.inventory.ItemStack;
 | 
			
		||||
import org.bukkit.inventory.SmithingInventory;
 | 
			
		||||
 | 
			
		||||
public class SmithingTableCraftHandler extends SmithingTableListener
 | 
			
		||||
{
 | 
			
		||||
    public SmithingTableCraftHandler(final ArmoredElytra plugin)
 | 
			
		||||
    {
 | 
			
		||||
        super(plugin, true);
 | 
			
		||||
        // Register the anvil handler with creation disabled so AEs can still be repaired and stuff.
 | 
			
		||||
        Bukkit.getPluginManager().registerEvents(new AnvilHandler(plugin, false), plugin);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @EventHandler(ignoreCancelled = true)
 | 
			
		||||
    public void onSmithingTableUsage(final PrepareSmithingEvent event)
 | 
			
		||||
    {
 | 
			
		||||
        super.onSmithingTableUsage(event);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected ArmorTier getArmorTier(ItemStack itemStackA, ItemStack itemStackB)
 | 
			
		||||
    {
 | 
			
		||||
        if (itemStackA == null || itemStackB == null ||
 | 
			
		||||
            itemStackA.getType() != Material.ELYTRA || !Util.isChestPlate(itemStackB))
 | 
			
		||||
            return ArmorTier.NONE;
 | 
			
		||||
 | 
			
		||||
        return Util.armorToTier(itemStackB.getType());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @EventHandler(ignoreCancelled = true)
 | 
			
		||||
    public void onInventoryClick(InventoryClickEvent e)
 | 
			
		||||
    {
 | 
			
		||||
        if (!isAESmithingTableEvent(e))
 | 
			
		||||
            return;
 | 
			
		||||
        SmithingInventory smithingInventory = (SmithingInventory) e.getInventory();
 | 
			
		||||
        final ItemStack result = smithingInventory.getItem(2);
 | 
			
		||||
 | 
			
		||||
        // This cast may look unchecked, but it was checked by isSmithingTableEvent already.
 | 
			
		||||
        giveItemToPlayer((Player) e.getWhoClicked(), result, e.isShiftClick());
 | 
			
		||||
        smithingInventory.clear();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -3,11 +3,8 @@ package nl.pim16aap2.armoredElytra.handlers;
 | 
			
		||||
import nl.pim16aap2.armoredElytra.ArmoredElytra;
 | 
			
		||||
import nl.pim16aap2.armoredElytra.util.ArmorTier;
 | 
			
		||||
import nl.pim16aap2.armoredElytra.util.EnchantmentContainer;
 | 
			
		||||
import nl.pim16aap2.armoredElytra.util.Util;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.event.EventHandler;
 | 
			
		||||
import org.bukkit.event.Listener;
 | 
			
		||||
import org.bukkit.event.inventory.InventoryClickEvent;
 | 
			
		||||
import org.bukkit.event.inventory.InventoryType;
 | 
			
		||||
@@ -17,16 +14,19 @@ import org.bukkit.inventory.SmithingInventory;
 | 
			
		||||
 | 
			
		||||
import java.util.logging.Level;
 | 
			
		||||
 | 
			
		||||
public class SmithingTableHandler extends ArmoredElytraHandler implements Listener
 | 
			
		||||
abstract class SmithingTableListener extends ArmoredElytraHandler implements Listener
 | 
			
		||||
{
 | 
			
		||||
    public SmithingTableHandler(final ArmoredElytra plugin)
 | 
			
		||||
    public SmithingTableListener(ArmoredElytra plugin, boolean creationEnabled)
 | 
			
		||||
    {
 | 
			
		||||
        super(plugin, true);
 | 
			
		||||
        // Register the anvil handler with creation disabled so AEs can still be repaired and stuff.
 | 
			
		||||
        Bukkit.getPluginManager().registerEvents(new AnvilHandler(plugin, false), plugin);
 | 
			
		||||
        super(plugin, creationEnabled);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public SmithingTableListener(ArmoredElytra plugin)
 | 
			
		||||
    {
 | 
			
		||||
        this(plugin, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @EventHandler(ignoreCancelled = true)
 | 
			
		||||
    public void onSmithingTableUsage(final PrepareSmithingEvent event)
 | 
			
		||||
    {
 | 
			
		||||
        final SmithingInventory inventory = event.getInventory();
 | 
			
		||||
@@ -35,11 +35,10 @@ public class SmithingTableHandler extends ArmoredElytraHandler implements Listen
 | 
			
		||||
        final ItemStack itemStackA = contents[0];
 | 
			
		||||
        final ItemStack itemStackB = contents[1];
 | 
			
		||||
 | 
			
		||||
        if (itemStackA == null || itemStackB == null ||
 | 
			
		||||
            itemStackA.getType() != Material.ELYTRA || !Util.isChestPlate(itemStackB))
 | 
			
		||||
        final ArmorTier newTier = getArmorTier(itemStackA, itemStackB);
 | 
			
		||||
        if (newTier == ArmorTier.NONE)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        final ArmorTier newTier = Util.armorToTier(itemStackB.getType());
 | 
			
		||||
        EnchantmentContainer enchantments = EnchantmentContainer.getEnchantments(itemStackA, plugin);
 | 
			
		||||
        final Player player = (Player) event.getView().getPlayer();
 | 
			
		||||
 | 
			
		||||
@@ -54,24 +53,40 @@ public class SmithingTableHandler extends ArmoredElytraHandler implements Listen
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Let the player take items out of the smithing table.
 | 
			
		||||
    @EventHandler(ignoreCancelled = true)
 | 
			
		||||
    public void onInventoryClick(InventoryClickEvent e)
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks if the provided input {@link ItemStack}s form a valid input pattern for a smithing table, and, if so,
 | 
			
		||||
     * which tier it combines into.
 | 
			
		||||
     *
 | 
			
		||||
     * @param itemStackA The first {@link ItemStack}.
 | 
			
		||||
     * @param itemStackB The second {@link ItemStack}.
 | 
			
		||||
     * @return The {@link ArmorTier} as figured out from the input pattern. If the pattern is invalid, {@link
 | 
			
		||||
     * ArmorTier#NONE} is returned.
 | 
			
		||||
     */
 | 
			
		||||
    protected abstract ArmorTier getArmorTier(ItemStack itemStackA, ItemStack itemStackB);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks if an {@link InventoryClickEvent} is useful for this plugin. I.e., it is about a smithing inventory and
 | 
			
		||||
     * there is an (armored) elytra involved somehow.
 | 
			
		||||
     *
 | 
			
		||||
     * @param event The {@link InventoryClickEvent} which may be of use to us.
 | 
			
		||||
     * @return True if this plugin can process this event further.
 | 
			
		||||
     */
 | 
			
		||||
    protected boolean isAESmithingTableEvent(final InventoryClickEvent event)
 | 
			
		||||
    {
 | 
			
		||||
        if (e.getRawSlot() != 2 || !(e.getWhoClicked() instanceof Player))
 | 
			
		||||
            return;
 | 
			
		||||
        if (event.getRawSlot() != 2)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        // Check if the event was a player who interacted with a smithing table.
 | 
			
		||||
        Player player = (Player) e.getWhoClicked();
 | 
			
		||||
        if (e.getView().getType() != InventoryType.SMITHING)
 | 
			
		||||
            return;
 | 
			
		||||
        Player player = (Player) event.getWhoClicked();
 | 
			
		||||
        if (event.getView().getType() != InventoryType.SMITHING)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        SmithingInventory smithingInventory;
 | 
			
		||||
        // Try to cast inventory being used in the event to a smithing inventory.
 | 
			
		||||
        // This will throw a ClassCastException when a CraftInventoryCustom is used.
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            smithingInventory = (SmithingInventory) e.getInventory();
 | 
			
		||||
            smithingInventory = (SmithingInventory) event.getInventory();
 | 
			
		||||
        }
 | 
			
		||||
        catch (ClassCastException exception)
 | 
			
		||||
        {
 | 
			
		||||
@@ -80,15 +95,19 @@ public class SmithingTableHandler extends ArmoredElytraHandler implements Listen
 | 
			
		||||
            plugin.debugMsg(Level.WARNING, "Could not cast inventory to SmithingInventory for player " +
 | 
			
		||||
                player.getName() + "! Armored Elytras cannot be crafted!");
 | 
			
		||||
            exception.printStackTrace();
 | 
			
		||||
            return;
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        final ItemStack result = smithingInventory.getItem(2);
 | 
			
		||||
        if (result == null || result.getType() != Material.ELYTRA ||
 | 
			
		||||
            ArmoredElytra.getInstance().getNbtEditor().getArmorTier(result) == ArmorTier.NONE)
 | 
			
		||||
            return;
 | 
			
		||||
        if (smithingInventory.getItem(0) == null ||
 | 
			
		||||
            smithingInventory.getItem(1) == null ||
 | 
			
		||||
            smithingInventory.getItem(2) == null)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        giveItemToPlayer(player, result, e.isShiftClick());
 | 
			
		||||
        smithingInventory.clear();
 | 
			
		||||
        final ItemStack result = smithingInventory.getItem(2);
 | 
			
		||||
        if (result.getType() != Material.ELYTRA ||
 | 
			
		||||
            ArmoredElytra.getInstance().getNbtEditor().getArmorTier(result) == ArmorTier.NONE)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -35,6 +35,7 @@ public class ConfigLoader
 | 
			
		||||
    private LinkedHashSet<Enchantment> allowedEnchantments;
 | 
			
		||||
    private boolean allowMultipleProtectionEnchantments;
 | 
			
		||||
    private boolean craftingInSmithingTable;
 | 
			
		||||
    private boolean allowUpgradeToNetherite;
 | 
			
		||||
    private boolean bypassWearPerm;
 | 
			
		||||
    private boolean bypassCraftPerm;
 | 
			
		||||
    private boolean allowRenaming;
 | 
			
		||||
@@ -126,6 +127,12 @@ public class ConfigLoader
 | 
			
		||||
                "This option only works on 1.16+! When enabled, armored elytra creation in anvils is disabled. ",
 | 
			
		||||
                "Instead, you will have to craft them in a smithy. Enchanting/repairing them still works via the anvil."
 | 
			
		||||
            };
 | 
			
		||||
        String[] allowUpgradeToNetheriteComment =
 | 
			
		||||
            {
 | 
			
		||||
                "Whether or not to allow upgrading diamond armored elytras to netherite ones is possible.",
 | 
			
		||||
                "When allowed (on 1.16+), you can combine a diamond one with a netherite ingot in a smithing table",
 | 
			
		||||
                "and you'll receive a netherite one."
 | 
			
		||||
            };
 | 
			
		||||
        String[] allowRenamingComment =
 | 
			
		||||
            {
 | 
			
		||||
                "Whether or not to allow renaming of armored elytras in anvils."
 | 
			
		||||
@@ -158,6 +165,14 @@ public class ConfigLoader
 | 
			
		||||
                "but this is only supported on 1.16+! Reverting to disabled.");
 | 
			
		||||
            craftingInSmithingTable = false;
 | 
			
		||||
        }
 | 
			
		||||
        allowUpgradeToNetherite = addNewConfigOption(config, "allowUpgradeToNetherite", smithingTableAllowed,
 | 
			
		||||
                                                     allowUpgradeToNetheriteComment);
 | 
			
		||||
        if (allowUpgradeToNetherite && !smithingTableAllowed)
 | 
			
		||||
        {
 | 
			
		||||
            Bukkit.getLogger().log(Level.WARNING, "You tried to enable crafting in smithing tables, " +
 | 
			
		||||
                "but this is only supported on 1.16+! Reverting to disabled.");
 | 
			
		||||
            allowUpgradeToNetherite = false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        defaultAllowedEnchantments = addNewConfigOption(config, "allowedEnchantments", defaultAllowedEnchantments,
 | 
			
		||||
                                                        enchantmentsComment);
 | 
			
		||||
@@ -258,6 +273,11 @@ public class ConfigLoader
 | 
			
		||||
        return craftingInSmithingTable;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean allowUpgradeToNetherite()
 | 
			
		||||
    {
 | 
			
		||||
        return allowUpgradeToNetherite;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean unbreakable()
 | 
			
		||||
    {
 | 
			
		||||
        return unbreakable;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user