Use builder for creating armored elytras
- All armored elytra creation/modification is now handled by the ArmoredElytraBuilder class. - When creating a new armored elytra, the existing NBT data is now no longer removed.
This commit is contained in:
parent
daafa5572c
commit
4c8cf55021
@ -9,11 +9,11 @@ import nl.pim16aap2.armoredElytra.handlers.LoginHandler;
|
||||
import nl.pim16aap2.armoredElytra.handlers.NetheriteUpgradeListener;
|
||||
import nl.pim16aap2.armoredElytra.handlers.SmithingTableCraftHandler;
|
||||
import nl.pim16aap2.armoredElytra.handlers.Uninstaller;
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.DurabilityManager;
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
|
||||
import nl.pim16aap2.armoredElytra.util.ArmorTier;
|
||||
import nl.pim16aap2.armoredElytra.util.ArmorTierName;
|
||||
import nl.pim16aap2.armoredElytra.util.ConfigLoader;
|
||||
import nl.pim16aap2.armoredElytra.util.DurabilityManager;
|
||||
import nl.pim16aap2.armoredElytra.util.MinecraftVersion;
|
||||
import nl.pim16aap2.armoredElytra.util.UpdateManager;
|
||||
import nl.pim16aap2.armoredElytra.util.messages.Message;
|
||||
@ -22,7 +22,7 @@ import org.bstats.bukkit.Metrics;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
@ -183,13 +183,13 @@ public class ArmoredElytra extends JavaPlugin implements Listener
|
||||
messages.getString(Message.TIER_SHORT_NETHERITE)));
|
||||
}
|
||||
|
||||
public boolean playerHasCraftPerm(Player player, ArmorTier armorTier)
|
||||
public boolean playerHasCraftPerm(HumanEntity player, ArmorTier armorTier)
|
||||
{
|
||||
return getConfigLoader().bypassCraftPerm() ||
|
||||
player.hasPermission("armoredelytra.craft." + ArmorTier.getName(armorTier));
|
||||
}
|
||||
|
||||
public boolean playerHasWearPerm(Player player, ArmorTier armorTier)
|
||||
public boolean playerHasWearPerm(HumanEntity player, ArmorTier armorTier)
|
||||
{
|
||||
return getConfigLoader().bypassWearPerm() ||
|
||||
player.hasPermission("armoredelytra.wear." + ArmorTier.getName(armorTier));
|
||||
@ -202,13 +202,13 @@ public class ArmoredElytra extends JavaPlugin implements Listener
|
||||
}
|
||||
|
||||
// Send a message to a player in a specific color.
|
||||
public void messagePlayer(Player player, ChatColor color, String str)
|
||||
public void messagePlayer(HumanEntity player, ChatColor color, String str)
|
||||
{
|
||||
player.sendMessage(color + str);
|
||||
}
|
||||
|
||||
// Send a message to a player.
|
||||
public void messagePlayer(Player player, String str)
|
||||
public void messagePlayer(HumanEntity player, String str)
|
||||
{
|
||||
messagePlayer(player, ChatColor.WHITE, str);
|
||||
}
|
||||
@ -222,7 +222,7 @@ public class ArmoredElytra extends JavaPlugin implements Listener
|
||||
}
|
||||
|
||||
// Send the usageDeniedMessage message to the player.
|
||||
public void usageDeniedMessage(Player player, ArmorTier armorTier)
|
||||
public void usageDeniedMessage(HumanEntity player, ArmorTier armorTier)
|
||||
{
|
||||
final String message = getMessageWithTierNames(Message.MESSAGES_USAGEDENIED, armorTier);
|
||||
if (!message.equals("NONE"))
|
||||
@ -230,14 +230,14 @@ public class ArmoredElytra extends JavaPlugin implements Listener
|
||||
}
|
||||
|
||||
// Send the elytraReceivedMessage message to the player.
|
||||
public void elytraReceivedMessage(Player player, ArmorTier armorTier)
|
||||
public void elytraReceivedMessage(HumanEntity player, ArmorTier armorTier)
|
||||
{
|
||||
final String message = getMessageWithTierNames(Message.MESSAGES_ELYTRARECEIVED, armorTier);
|
||||
if (!message.equals("NONE"))
|
||||
messagePlayer(player, ChatColor.GREEN, message);
|
||||
}
|
||||
|
||||
public void sendNoGivePermissionMessage(Player player, ArmorTier armorTier)
|
||||
public void sendNoGivePermissionMessage(HumanEntity player, ArmorTier armorTier)
|
||||
{
|
||||
final String message = getMessageWithTierNames(Message.MESSAGES_NOGIVEPERMISSION, armorTier);
|
||||
messagePlayer(player, ChatColor.RED, message);
|
||||
@ -263,7 +263,7 @@ public class ArmoredElytra extends JavaPlugin implements Listener
|
||||
}
|
||||
|
||||
// Give the provided player the provided item.
|
||||
public void giveArmoredElytraToPlayer(Player player, ItemStack item)
|
||||
public void giveArmoredElytraToPlayer(HumanEntity player, ItemStack item)
|
||||
{
|
||||
if (item != null)
|
||||
player.getInventory().addItem(item);
|
||||
|
@ -1,16 +1,14 @@
|
||||
package nl.pim16aap2.armoredElytra.handlers;
|
||||
|
||||
import nl.pim16aap2.armoredElytra.ArmoredElytra;
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.DurabilityManager;
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
|
||||
import nl.pim16aap2.armoredElytra.util.Action;
|
||||
import nl.pim16aap2.armoredElytra.util.ArmorTier;
|
||||
import nl.pim16aap2.armoredElytra.util.ConfigLoader;
|
||||
import nl.pim16aap2.armoredElytra.util.DurabilityManager;
|
||||
import nl.pim16aap2.armoredElytra.util.EnchantmentContainer;
|
||||
import nl.pim16aap2.armoredElytra.util.Util;
|
||||
import nl.pim16aap2.armoredElytra.util.XMaterial;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@ -23,6 +21,7 @@ import org.bukkit.inventory.AnvilInventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class AnvilHandler extends ArmoredElytraHandler implements Listener
|
||||
@ -49,7 +48,7 @@ public class AnvilHandler extends ArmoredElytraHandler implements Listener
|
||||
// Ignoring:
|
||||
// - Elytra (not armored) + !chestplate -> None
|
||||
// - * + * -> None
|
||||
private Action isValidInput(ItemStack itemOne, ItemStack itemTwo)
|
||||
private Action isValidInput(ArmorTier itemOneTier, ItemStack itemOne, ItemStack itemTwo)
|
||||
{
|
||||
if (itemOne == null || itemTwo == null)
|
||||
return Action.NONE;
|
||||
@ -57,32 +56,30 @@ public class AnvilHandler extends ArmoredElytraHandler implements Listener
|
||||
if (itemOne.getType() != Material.ELYTRA)
|
||||
return Action.NONE;
|
||||
|
||||
Material matTwo = itemTwo.getType();
|
||||
final Material matTwo = itemTwo.getType();
|
||||
|
||||
// If the elytra is to be combined with chest armor...
|
||||
if (Util.isChestPlate(matTwo))
|
||||
return creationEnabled ? Action.CREATE : Action.NONE;
|
||||
|
||||
ArmorTier tier = nbtEditor.getArmorTier(itemOne);
|
||||
|
||||
if (tier != ArmorTier.NONE)
|
||||
if (itemOneTier != ArmorTier.NONE)
|
||||
{
|
||||
// If the armored elytra is to be enchanted using an enchanted book...
|
||||
if (matTwo == Material.ENCHANTED_BOOK)
|
||||
return config.allowAddingEnchantments() ? Action.ENCHANT : Action.BLOCK;
|
||||
|
||||
// If the armored elytra is to be repaired using its repair item...
|
||||
if (ArmorTier.getRepairItem(tier) == matTwo)
|
||||
return durabilityManager.getRealDurability(itemOne, tier) == 0 ? Action.BLOCK : Action.REPAIR;
|
||||
if (ArmorTier.getRepairItem(itemOneTier) == matTwo)
|
||||
return durabilityManager.getRealDurability(itemOne, itemOneTier) == 0 ? Action.BLOCK : Action.REPAIR;
|
||||
|
||||
// If the armored elytra is to be combined with another armored elytra of the same tier...
|
||||
if (nbtEditor.getArmorTier(itemTwo) == tier)
|
||||
if (nbtEditor.getArmorTier(itemTwo) == itemOneTier)
|
||||
return creationEnabled ? Action.COMBINE : Action.NONE;
|
||||
|
||||
// If the armored elytra is not of the leather tier, but itemTwo is leather,
|
||||
// Pick the block action, as that would repair the elytra by default (vanilla).
|
||||
// Also block Armored Elytra + Elytra and Elytra + Membrane
|
||||
if (tier != ArmorTier.LEATHER && matTwo == Material.LEATHER || matTwo == Material.ELYTRA ||
|
||||
if (itemOneTier != ArmorTier.LEATHER && matTwo == Material.LEATHER || matTwo == Material.ELYTRA ||
|
||||
matTwo.equals(XMaterial.PHANTOM_MEMBRANE.parseMaterial()))
|
||||
return Action.BLOCK;
|
||||
}
|
||||
@ -93,10 +90,11 @@ public class AnvilHandler extends ArmoredElytraHandler implements Listener
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
private void onAnvilInventoryOpen(PrepareAnvilEvent event)
|
||||
{
|
||||
Player player = (Player) event.getView().getPlayer();
|
||||
if (!(event.getView().getPlayer() instanceof Player player))
|
||||
return;
|
||||
|
||||
ItemStack itemA = event.getInventory().getItem(0);
|
||||
ItemStack itemB = event.getInventory().getItem(1);
|
||||
ItemStack result;
|
||||
|
||||
if (itemA != null && itemB != null)
|
||||
// If itemB is the (armored) elytra, while itemA isn't, switch itemA and itemB.
|
||||
@ -107,81 +105,57 @@ public class AnvilHandler extends ArmoredElytraHandler implements Listener
|
||||
itemB = tmp;
|
||||
}
|
||||
|
||||
// Check if there are items in both input slots.
|
||||
if (itemA != null && itemB != null)
|
||||
{
|
||||
final Action action = isValidInput(itemA, itemB);
|
||||
ArmorTier newTier = ArmorTier.NONE;
|
||||
final ArmorTier curTier = nbtEditor.getArmorTier(itemA);
|
||||
|
||||
int newDurability = 0;
|
||||
final EnchantmentContainer enchantments = EnchantmentContainer.getEnchantments(itemA, plugin);
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case REPAIR:
|
||||
newTier = curTier;
|
||||
newDurability = durabilityManager.getRepairedDurability(itemA, itemB.getAmount(), curTier);
|
||||
break;
|
||||
case COMBINE:
|
||||
newTier = curTier;
|
||||
newDurability = durabilityManager.getCombinedDurability(itemA, itemB, curTier, newTier);
|
||||
enchantments.merge(EnchantmentContainer.getEnchantments(itemB, plugin));
|
||||
break;
|
||||
case CREATE:
|
||||
newTier = Util.armorToTier(itemB.getType());
|
||||
newDurability = durabilityManager.getCombinedDurability(itemA, itemB, curTier, newTier);
|
||||
enchantments.merge(EnchantmentContainer.getEnchantments(itemB, plugin));
|
||||
break;
|
||||
case ENCHANT:
|
||||
newTier = curTier;
|
||||
newDurability = durabilityManager.getRealDurability(itemA, newTier);
|
||||
|
||||
// If there aren't any illegal enchantments on the book, continue as normal.
|
||||
// Otherwise... Block.
|
||||
final EnchantmentContainer enchantmentsB = EnchantmentContainer.getEnchantments(itemB, plugin);
|
||||
if (enchantmentsB.getEnchantmentCount() > 0)
|
||||
{
|
||||
enchantments.merge(enchantmentsB);
|
||||
break;
|
||||
}
|
||||
//$FALL-THROUGH$
|
||||
case BLOCK:
|
||||
event.setResult(null);
|
||||
player.updateInventory();
|
||||
//$FALL-THROUGH$
|
||||
case NONE:
|
||||
return;
|
||||
}
|
||||
|
||||
if (plugin.playerHasCraftPerm(player, newTier))
|
||||
{
|
||||
result = new ItemStack(Material.ELYTRA, 1);
|
||||
enchantments.applyEnchantments(result);
|
||||
durabilityManager.setDurability(result, newDurability, newTier);
|
||||
|
||||
final String name = getElytraResultName(itemA, action, newTier, event.getInventory().getRenameText());
|
||||
final Color color = getItemColor(itemA, itemB);
|
||||
|
||||
result = nbtEditor.addArmorNBTTags(result, newTier, config.unbreakable(), name, color);
|
||||
|
||||
event.setResult(result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If one of the input items is null and the other an armored elytra, remove the result.
|
||||
// This prevents some naming issues.
|
||||
if ((itemA == null ^ itemB == null) &&
|
||||
nbtEditor.getArmorTier(itemA == null ? itemB : itemA) != ArmorTier.NONE)
|
||||
event.setResult(null);
|
||||
|
||||
if (itemA == null || itemB == null)
|
||||
return;
|
||||
|
||||
final ArmorTier currentArmorTier = nbtEditor.getArmorTier(itemA);
|
||||
final Action action = isValidInput(currentArmorTier, itemA, itemB);
|
||||
|
||||
if (action == Action.NONE)
|
||||
return;
|
||||
|
||||
final ArmorTier newArmorTier;
|
||||
if (action == Action.CREATE)
|
||||
newArmorTier = Util.armorToTier(itemB);
|
||||
else if (action == Action.COMBINE)
|
||||
newArmorTier = nbtEditor.getArmorTier(itemB);
|
||||
else
|
||||
newArmorTier = currentArmorTier;
|
||||
|
||||
final @Nullable String name = getElytraResultName(itemA, action, currentArmorTier, newArmorTier,
|
||||
event.getInventory().getRenameText());
|
||||
|
||||
final @Nullable ItemStack result =
|
||||
!plugin.playerHasCraftPerm(player, newArmorTier) ? null :
|
||||
switch (action)
|
||||
{
|
||||
case REPAIR -> armoredElytraBuilder.repair(itemA, itemB, name);
|
||||
case ENCHANT -> armoredElytraBuilder.enchant(itemA, itemB, name);
|
||||
case COMBINE, CREATE -> armoredElytraBuilder.combine(itemA, itemB, newArmorTier, name);
|
||||
case BLOCK -> null;
|
||||
//noinspection ConstantConditions
|
||||
case NONE -> itemA;
|
||||
};
|
||||
|
||||
event.setResult(result);
|
||||
player.updateInventory();
|
||||
}
|
||||
|
||||
private String getElytraResultName(final ItemStack baseItem, final Action action,
|
||||
final ArmorTier armorTier, final String renameText)
|
||||
private @Nullable String getElytraResultName(final ItemStack baseItem, final Action action,
|
||||
final ArmorTier currentArmorTier, final ArmorTier newArmorTier,
|
||||
final String renameText)
|
||||
{
|
||||
final String tierName = plugin.getArmoredElytraName(armorTier);
|
||||
if (renameText == null || !config.allowRenaming())
|
||||
final String currentTierName = plugin.getArmoredElytraName(currentArmorTier);
|
||||
final String tierName = plugin.getArmoredElytraName(newArmorTier);
|
||||
|
||||
if (renameText == null || !config.allowRenaming() ||
|
||||
ChatColor.stripColor(currentTierName).equals(ChatColor.stripColor(renameText)))
|
||||
return tierName;
|
||||
|
||||
final ItemMeta meta = baseItem.getItemMeta();
|
||||
@ -201,11 +175,10 @@ public class AnvilHandler extends ArmoredElytraHandler implements Listener
|
||||
@EventHandler
|
||||
public void onInventoryClick(InventoryClickEvent e)
|
||||
{
|
||||
if (e.getRawSlot() != 2 || !(e.getWhoClicked() instanceof Player))
|
||||
if (e.getRawSlot() != 2 || !(e.getWhoClicked() instanceof Player player))
|
||||
return;
|
||||
|
||||
// Check if the event was a player who interacted with an anvil.
|
||||
Player player = (Player) e.getWhoClicked();
|
||||
if (e.getView().getType() != InventoryType.ANVIL)
|
||||
return;
|
||||
|
||||
@ -226,17 +199,18 @@ public class AnvilHandler extends ArmoredElytraHandler implements Listener
|
||||
return;
|
||||
}
|
||||
|
||||
if (anvilInventory.getItem(0) != null && anvilInventory.getItem(1) != null &&
|
||||
anvilInventory.getItem(2) != null && anvilInventory.getItem(2).getType() == Material.ELYTRA)
|
||||
final @Nullable ItemStack item0 = anvilInventory.getItem(0);
|
||||
final @Nullable ItemStack item1 = anvilInventory.getItem(1);
|
||||
final @Nullable ItemStack item2 = anvilInventory.getItem(2);
|
||||
|
||||
if (item0 != null && item1 != null && item2 != null && item2.getType() == Material.ELYTRA)
|
||||
{
|
||||
ArmorTier armortier = nbtEditor.getArmorTier(anvilInventory.getItem(2));
|
||||
final ArmorTier armortier = nbtEditor.getArmorTier(anvilInventory.getItem(2));
|
||||
|
||||
// If there's an armored elytra in the final slot...
|
||||
if (armortier != ArmorTier.NONE && plugin.playerHasCraftPerm(player, armortier))
|
||||
{
|
||||
final ItemStack result = anvilInventory.getItem(2);
|
||||
// Give the result to the player and clear the anvil's inventory.
|
||||
if (!giveItemToPlayer(player, result, e.isShiftClick()))
|
||||
if (!giveItemToPlayer(player, item2, e.isShiftClick()))
|
||||
return;
|
||||
|
||||
// Clean the anvil's inventory after transferring the items.
|
||||
|
@ -1,15 +1,12 @@
|
||||
package nl.pim16aap2.armoredElytra.handlers;
|
||||
|
||||
import nl.pim16aap2.armoredElytra.ArmoredElytra;
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.ArmoredElytraBuilder;
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.DurabilityManager;
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
|
||||
import nl.pim16aap2.armoredElytra.util.ConfigLoader;
|
||||
import nl.pim16aap2.armoredElytra.util.DurabilityManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.LeatherArmorMeta;
|
||||
|
||||
import javax.annotation.CheckReturnValue;
|
||||
|
||||
@ -20,55 +17,30 @@ import javax.annotation.CheckReturnValue;
|
||||
*/
|
||||
abstract class ArmoredElytraHandler
|
||||
{
|
||||
private static final Color DEFAULT_LEATHER_COLOR = Bukkit.getServer().getItemFactory().getDefaultLeatherColor();
|
||||
|
||||
protected final ArmoredElytra plugin;
|
||||
protected final boolean creationEnabled;
|
||||
protected final ConfigLoader config;
|
||||
protected final NBTEditor nbtEditor;
|
||||
protected final DurabilityManager durabilityManager;
|
||||
protected final ArmoredElytraBuilder armoredElytraBuilder;
|
||||
|
||||
protected ArmoredElytraHandler(ArmoredElytra plugin, boolean creationEnabled, NBTEditor nbtEditor,
|
||||
DurabilityManager durabilityManager, ConfigLoader config)
|
||||
DurabilityManager durabilityManager, ConfigLoader config,
|
||||
ArmoredElytraBuilder armoredElytraBuilder)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
this.creationEnabled = creationEnabled;
|
||||
this.nbtEditor = nbtEditor;
|
||||
this.durabilityManager = durabilityManager;
|
||||
this.config = config;
|
||||
this.armoredElytraBuilder = armoredElytraBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the color of the item if the item has a color.
|
||||
* <p>
|
||||
* See {@link LeatherArmorMeta#getColor()}.
|
||||
*
|
||||
* @param itemA The first {@link ItemStack} to check.
|
||||
* @param itemB The second {@link ItemStack} to check.
|
||||
* @return The color of the item, if it has a color, otherwise null.
|
||||
*/
|
||||
protected Color getItemColor(final ItemStack itemA, final ItemStack itemB)
|
||||
protected ArmoredElytraHandler(ArmoredElytra plugin, boolean creationEnabled, NBTEditor nbtEditor,
|
||||
DurabilityManager durabilityManager, ConfigLoader config)
|
||||
{
|
||||
final Color colorA = getItemColor(itemA);
|
||||
if (colorA != null && !colorA.equals(DEFAULT_LEATHER_COLOR))
|
||||
return colorA;
|
||||
|
||||
final Color colorB = getItemColor(itemB);
|
||||
return colorB != null ? colorB : colorA;
|
||||
}
|
||||
|
||||
private Color getItemColor(final ItemStack itemStack)
|
||||
{
|
||||
if (itemStack == null)
|
||||
return null;
|
||||
|
||||
if (itemStack.getType() == Material.ELYTRA)
|
||||
return nbtEditor.getColorOfArmoredElytra(itemStack);
|
||||
|
||||
if (!itemStack.hasItemMeta() || !(itemStack.getItemMeta() instanceof LeatherArmorMeta))
|
||||
return null;
|
||||
|
||||
return ((LeatherArmorMeta) itemStack.getItemMeta()).getColor();
|
||||
this(plugin, creationEnabled, nbtEditor, durabilityManager, config,
|
||||
new ArmoredElytraBuilder(nbtEditor, durabilityManager, config, plugin));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -76,8 +48,8 @@ abstract class ArmoredElytraHandler
|
||||
*
|
||||
* @param player The player to give the item to.
|
||||
* @param item The item to give.
|
||||
* @param direct Whether or not to put it in the player's inventory. When set to false it will be put in their
|
||||
* cursor instead.
|
||||
* @param direct Whether to put it in the player's inventory. When set to false it will be put in their cursor
|
||||
* instead.
|
||||
* @return True if the item could be given to the player, otherwise false (e.g. when their inventory is full).
|
||||
*/
|
||||
@CheckReturnValue
|
||||
|
@ -1,13 +1,13 @@
|
||||
package nl.pim16aap2.armoredElytra.handlers;
|
||||
|
||||
import nl.pim16aap2.armoredElytra.ArmoredElytra;
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.ArmoredElytraBuilder;
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.DurabilityManager;
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
|
||||
import nl.pim16aap2.armoredElytra.util.ArmorTier;
|
||||
import nl.pim16aap2.armoredElytra.util.DurabilityManager;
|
||||
import nl.pim16aap2.armoredElytra.util.messages.Message;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
@ -23,15 +23,13 @@ import java.util.logging.Level;
|
||||
public class CommandHandler implements CommandExecutor
|
||||
{
|
||||
private final ArmoredElytra plugin;
|
||||
private final NBTEditor nbtEditor;
|
||||
private final DurabilityManager durabilityManager;
|
||||
private static Field BY_KEY_FIELD;
|
||||
private final ArmoredElytraBuilder armoredElytraBuilder;
|
||||
|
||||
public CommandHandler(ArmoredElytra plugin, NBTEditor nbtEditor, DurabilityManager durabilityManager)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
this.nbtEditor = nbtEditor;
|
||||
this.durabilityManager = durabilityManager;
|
||||
armoredElytraBuilder = new ArmoredElytraBuilder(nbtEditor, durabilityManager, plugin.getConfigLoader(), plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -86,10 +84,7 @@ public class CommandHandler implements CommandExecutor
|
||||
if (allowed)
|
||||
{
|
||||
plugin.elytraReceivedMessage(receiver, armorTier);
|
||||
newElytra = nbtEditor.addArmorNBTTags(new ItemStack(Material.ELYTRA, 1), armorTier,
|
||||
plugin.getConfigLoader().unbreakable());
|
||||
durabilityManager.setDurability(newElytra, 0, armorTier);
|
||||
plugin.giveArmoredElytraToPlayer(receiver, newElytra);
|
||||
plugin.giveArmoredElytraToPlayer(receiver, armoredElytraBuilder.newArmoredElytra(armorTier));
|
||||
}
|
||||
else
|
||||
plugin.sendNoGivePermissionMessage(player, armorTier);
|
||||
@ -115,7 +110,6 @@ public class CommandHandler implements CommandExecutor
|
||||
|
||||
if (args.length == 2)
|
||||
{
|
||||
ItemStack newElytra;
|
||||
final String tier = args[1];
|
||||
player = Bukkit.getPlayer(args[0]);
|
||||
if (player != null)
|
||||
@ -125,11 +119,7 @@ public class CommandHandler implements CommandExecutor
|
||||
return false;
|
||||
|
||||
plugin.elytraReceivedMessage(player, armorTier);
|
||||
newElytra = nbtEditor.addArmorNBTTags(new ItemStack(Material.ELYTRA, 1), armorTier,
|
||||
plugin.getConfigLoader().unbreakable());
|
||||
durabilityManager.setDurability(newElytra, 0, armorTier);
|
||||
|
||||
plugin.giveArmoredElytraToPlayer(player, newElytra);
|
||||
plugin.giveArmoredElytraToPlayer(player, armoredElytraBuilder.newArmoredElytra(armorTier));
|
||||
plugin.myLogger(Level.INFO, ("Giving an armored elytra of the " + ArmorTier.getArmor(armorTier) +
|
||||
" armor tier to player " + player.getName()));
|
||||
return true;
|
||||
|
@ -5,10 +5,10 @@ import nl.pim16aap2.armoredElytra.lib.armorequip.ArmorEquipEvent;
|
||||
import nl.pim16aap2.armoredElytra.lib.armorequip.ArmorListener;
|
||||
import nl.pim16aap2.armoredElytra.lib.armorequip.ArmorType;
|
||||
import nl.pim16aap2.armoredElytra.lib.armorequip.DispenserArmorListener;
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.DurabilityManager;
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
|
||||
import nl.pim16aap2.armoredElytra.util.AllowedToWearEnum;
|
||||
import nl.pim16aap2.armoredElytra.util.ArmorTier;
|
||||
import nl.pim16aap2.armoredElytra.util.DurabilityManager;
|
||||
import nl.pim16aap2.armoredElytra.util.Util;
|
||||
import nl.pim16aap2.armoredElytra.util.messages.Message;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -63,9 +63,8 @@ public class EventHandlers implements Listener
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerDamage(EntityDamageEvent e)
|
||||
{
|
||||
if (!(e.getEntity() instanceof Player))
|
||||
if (!(e.getEntity() instanceof final Player p))
|
||||
return;
|
||||
final Player p = (Player) e.getEntity();
|
||||
|
||||
final ItemStack elytra = p.getInventory().getChestplate();
|
||||
if (elytra == null)
|
||||
|
@ -1,8 +1,8 @@
|
||||
package nl.pim16aap2.armoredElytra.handlers;
|
||||
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.DurabilityManager;
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
|
||||
import nl.pim16aap2.armoredElytra.util.ArmorTier;
|
||||
import nl.pim16aap2.armoredElytra.util.DurabilityManager;
|
||||
import nl.pim16aap2.armoredElytra.util.Util;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.event.EventHandler;
|
||||
|
@ -1,18 +1,19 @@
|
||||
package nl.pim16aap2.armoredElytra.handlers;
|
||||
|
||||
import nl.pim16aap2.armoredElytra.ArmoredElytra;
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.DurabilityManager;
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
|
||||
import nl.pim16aap2.armoredElytra.util.ArmorTier;
|
||||
import nl.pim16aap2.armoredElytra.util.ConfigLoader;
|
||||
import nl.pim16aap2.armoredElytra.util.DurabilityManager;
|
||||
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;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class NetheriteUpgradeListener extends SmithingTableListener
|
||||
{
|
||||
public NetheriteUpgradeListener(final ArmoredElytra plugin, NBTEditor nbtEditor,
|
||||
@ -21,43 +22,47 @@ public class NetheriteUpgradeListener extends SmithingTableListener
|
||||
super(plugin, false, nbtEditor, durabilityManager, config);
|
||||
}
|
||||
|
||||
@Override @EventHandler(ignoreCancelled = true)
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onSmithingTableUsage(final PrepareSmithingEvent event)
|
||||
{
|
||||
super.onSmithingTableUsage(event);
|
||||
final SmithingInventory inventory = event.getInventory();
|
||||
final ItemStack[] contents = inventory.getContents();
|
||||
|
||||
final ItemStack itemStackA = contents[0];
|
||||
final ItemStack itemStackB = contents[1];
|
||||
|
||||
if (!validInput(itemStackA, itemStackB))
|
||||
return;
|
||||
|
||||
if (!plugin.playerHasCraftPerm(event.getView().getPlayer(), ArmorTier.NETHERITE))
|
||||
return;
|
||||
|
||||
event.setResult(armoredElytraBuilder
|
||||
.newBuilder()
|
||||
.ofElytra(itemStackA)
|
||||
.upgradeToTier(ArmorTier.NETHERITE)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ArmorTier getArmorTier(ItemStack itemStackA, ItemStack itemStackB)
|
||||
private boolean validInput(@Nullable ItemStack itemStackA, @Nullable 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;
|
||||
return false;
|
||||
|
||||
// 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;
|
||||
return itemStackA.getAmount() == 1 && itemStackB.getAmount() == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
@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();
|
||||
|
||||
if (!giveItemToPlayer(player, smithingInventory.getItem(2), event.isShiftClick()))
|
||||
return;
|
||||
smithingInventory.clear();
|
||||
super.onInventoryClick(event);
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,13 @@
|
||||
package nl.pim16aap2.armoredElytra.handlers;
|
||||
|
||||
import nl.pim16aap2.armoredElytra.ArmoredElytra;
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.DurabilityManager;
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
|
||||
import nl.pim16aap2.armoredElytra.util.ArmorTier;
|
||||
import nl.pim16aap2.armoredElytra.util.ConfigLoader;
|
||||
import nl.pim16aap2.armoredElytra.util.DurabilityManager;
|
||||
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;
|
||||
@ -26,15 +25,26 @@ public class SmithingTableCraftHandler extends SmithingTableListener
|
||||
.registerEvents(new AnvilHandler(plugin, false, nbtEditor, durabilityManager, config), plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onSmithingTableUsage(final PrepareSmithingEvent event)
|
||||
{
|
||||
super.onSmithingTableUsage(event);
|
||||
final SmithingInventory inventory = event.getInventory();
|
||||
final ItemStack[] contents = inventory.getContents();
|
||||
|
||||
final ItemStack itemStackA = contents[0];
|
||||
final ItemStack itemStackB = contents[1];
|
||||
|
||||
final ArmorTier newArmorTier = getNewArmorTier(itemStackA, itemStackB);
|
||||
if (newArmorTier == ArmorTier.NONE)
|
||||
return;
|
||||
|
||||
if (!plugin.playerHasCraftPerm(event.getView().getPlayer(), newArmorTier))
|
||||
return;
|
||||
|
||||
event.setResult(armoredElytraBuilder.combine(itemStackA, itemStackB, newArmorTier, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ArmorTier getArmorTier(ItemStack itemStackA, ItemStack itemStackB)
|
||||
protected ArmorTier getNewArmorTier(ItemStack itemStackA, ItemStack itemStackB)
|
||||
{
|
||||
if (itemStackA == null || itemStackB == null ||
|
||||
itemStackA.getType() != Material.ELYTRA || !Util.isChestPlate(itemStackB))
|
||||
@ -43,17 +53,10 @@ public class SmithingTableCraftHandler extends SmithingTableListener
|
||||
return Util.armorToTier(itemStackB.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onInventoryClick(InventoryClickEvent e)
|
||||
public void onInventoryClick(InventoryClickEvent event)
|
||||
{
|
||||
if (!isAESmithingTableEvent(e))
|
||||
return;
|
||||
final SmithingInventory smithingInventory = (SmithingInventory) e.getInventory();
|
||||
final ItemStack result = smithingInventory.getItem(2);
|
||||
|
||||
// This cast may look unchecked, but it was checked by isSmithingTableEvent already.
|
||||
if (!giveItemToPlayer((Player) e.getWhoClicked(), result, e.isShiftClick()))
|
||||
return;
|
||||
smithingInventory.clear();
|
||||
super.onInventoryClick(event);
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,15 @@
|
||||
package nl.pim16aap2.armoredElytra.handlers;
|
||||
|
||||
import nl.pim16aap2.armoredElytra.ArmoredElytra;
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.DurabilityManager;
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
|
||||
import nl.pim16aap2.armoredElytra.util.ArmorTier;
|
||||
import nl.pim16aap2.armoredElytra.util.ConfigLoader;
|
||||
import nl.pim16aap2.armoredElytra.util.DurabilityManager;
|
||||
import nl.pim16aap2.armoredElytra.util.EnchantmentContainer;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.event.inventory.PrepareSmithingEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.SmithingInventory;
|
||||
|
||||
@ -26,47 +23,19 @@ abstract class SmithingTableListener extends ArmoredElytraHandler implements Lis
|
||||
super(plugin, creationEnabled, nbtEditor, durabilityManager, config);
|
||||
}
|
||||
|
||||
public void onSmithingTableUsage(final PrepareSmithingEvent event)
|
||||
protected void onInventoryClick(InventoryClickEvent event)
|
||||
{
|
||||
final SmithingInventory inventory = event.getInventory();
|
||||
final ItemStack[] contents = inventory.getContents();
|
||||
|
||||
final ItemStack itemStackA = contents[0];
|
||||
final ItemStack itemStackB = contents[1];
|
||||
|
||||
final ArmorTier newTier = getArmorTier(itemStackA, itemStackB);
|
||||
if (newTier == ArmorTier.NONE)
|
||||
if (!isAESmithingTableEvent(event))
|
||||
return;
|
||||
final SmithingInventory smithingInventory = (SmithingInventory) event.getInventory();
|
||||
final ItemStack result = smithingInventory.getItem(2);
|
||||
|
||||
final Player player = (Player) event.getView().getPlayer();
|
||||
|
||||
if (plugin.playerHasCraftPerm(player, newTier))
|
||||
{
|
||||
final EnchantmentContainer enchantments = EnchantmentContainer.getEnchantments(itemStackA, plugin);
|
||||
enchantments.merge(EnchantmentContainer.getEnchantments(itemStackB, plugin));
|
||||
final Color color = getItemColor(itemStackA, itemStackB);
|
||||
|
||||
final ItemStack result = nbtEditor.addArmorNBTTags(new ItemStack(Material.ELYTRA, 1), newTier,
|
||||
plugin.getConfigLoader().unbreakable(), color);
|
||||
durabilityManager.setCombinedDurability(result, itemStackA, itemStackB,
|
||||
nbtEditor.getArmorTier(itemStackA), newTier);
|
||||
|
||||
enchantments.applyEnchantments(result);
|
||||
event.setResult(result);
|
||||
}
|
||||
// This cast may look unchecked, but it was checked by isSmithingTableEvent already.
|
||||
if (!giveItemToPlayer((Player) event.getWhoClicked(), result, event.isShiftClick()))
|
||||
return;
|
||||
smithingInventory.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
@ -0,0 +1,469 @@
|
||||
package nl.pim16aap2.armoredElytra.nbtEditor;
|
||||
|
||||
import nl.pim16aap2.armoredElytra.ArmoredElytra;
|
||||
import nl.pim16aap2.armoredElytra.util.ArmorTier;
|
||||
import nl.pim16aap2.armoredElytra.util.ConfigLoader;
|
||||
import nl.pim16aap2.armoredElytra.util.EnchantmentContainer;
|
||||
import nl.pim16aap2.armoredElytra.util.Util;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.LeatherArmorMeta;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings({"unused", "UnusedReturnValue", "ClassCanBeRecord"})
|
||||
public class ArmoredElytraBuilder
|
||||
{
|
||||
private final NBTEditor nbtEditor;
|
||||
private final DurabilityManager durabilityManager;
|
||||
private final ConfigLoader config;
|
||||
private final ArmoredElytra plugin;
|
||||
|
||||
public ArmoredElytraBuilder(NBTEditor nbtEditor, DurabilityManager durabilityManager,
|
||||
ConfigLoader config, ArmoredElytra plugin)
|
||||
{
|
||||
|
||||
this.nbtEditor = nbtEditor;
|
||||
this.durabilityManager = durabilityManager;
|
||||
this.config = config;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new builder for an armored elytra.
|
||||
*
|
||||
* @return The first step of the new builder.
|
||||
*/
|
||||
public IStep0 newBuilder()
|
||||
{
|
||||
return new Builder(nbtEditor, durabilityManager, config, plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for repairing an armored elytra.
|
||||
*
|
||||
* @param armoredElytra The armored elytra to repair.
|
||||
* @param repairItems The repair item(s) to use for repairing the armored elytra. It is assumed that they are of
|
||||
* the correct type.
|
||||
* @param name The new name of the output armored elytra. When this is null, {@link
|
||||
* ArmoredElytra#getArmoredElytraName(ArmorTier)} is used to set the name.
|
||||
* @return The new armored elytra.
|
||||
*/
|
||||
public @Nullable ItemStack repair(ItemStack armoredElytra, ItemStack repairItems, @Nullable String name)
|
||||
{
|
||||
return newBuilder().ofElytra(armoredElytra).repair(repairItems.getAmount()).withName(name).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for enchanting an armored elytra.
|
||||
*
|
||||
* @param armoredElytra The armored elytra to repair.
|
||||
* @param sourceItem The source item from which to copy the enchantments from.
|
||||
* @param name The new name of the output armored elytra. When this is null, {@link
|
||||
* ArmoredElytra#getArmoredElytraName(ArmorTier)} is used to set the name.
|
||||
* @return The new armored elytra.
|
||||
*/
|
||||
public @Nullable ItemStack enchant(ItemStack armoredElytra, ItemStack sourceItem, @Nullable String name)
|
||||
{
|
||||
final EnchantmentContainer enchantments = EnchantmentContainer.getEnchantments(sourceItem, plugin);
|
||||
if (enchantments.isEmpty())
|
||||
return null;
|
||||
return newBuilder().ofElytra(armoredElytra).addEnchantments(enchantments).withName(name).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for creating a new armored elytra from two items.
|
||||
*
|
||||
* @param elytra The input item. This should be an (armored) elytra.
|
||||
* @param combiner The item to combine with the elytra. This should either be an armored elytra of the same
|
||||
* non-NONE tier as the input elytra or a chestplate.
|
||||
* @param armorTier The armor tier of the input item. If this is not known, use {@link #combine(ItemStack,
|
||||
* ItemStack, String)} instead.
|
||||
* @param name The new name of the output armored elytra. When this is null, {@link
|
||||
* ArmoredElytra#getArmoredElytraName(ArmorTier)} is used to set the name.
|
||||
* @return The new armored elytra.
|
||||
*/
|
||||
public ItemStack combine(ItemStack elytra, ItemStack combiner, ArmorTier armorTier, @Nullable String name)
|
||||
{
|
||||
return newBuilder().ofElytra(elytra).combineWith(combiner, armorTier).withName(name).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link #combine(ItemStack, ItemStack, ArmorTier, String)} for unknown armor tiers.
|
||||
*/
|
||||
public ItemStack combine(ItemStack elytra, ItemStack combiner, @Nullable String name)
|
||||
{
|
||||
return newBuilder().ofElytra(elytra).combineWith(combiner).withName(name).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new armored elytra of a specific tier.
|
||||
*
|
||||
* @param armorTier The tier of the new armored elytra.
|
||||
* @return The new armored elytra.
|
||||
*/
|
||||
public ItemStack newArmoredElytra(ArmorTier armorTier)
|
||||
{
|
||||
return newBuilder().newItem(armorTier).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the third and last step of the armored elytra build process.
|
||||
*/
|
||||
public interface IStep2
|
||||
{
|
||||
/**
|
||||
* Specifies the new name of the armored elytra.
|
||||
*
|
||||
* @param name The new name of the armored elytra. When this is null (default), the default name for the new
|
||||
* tier will be used.
|
||||
* @return The current builder step.
|
||||
*/
|
||||
IStep2 withName(@Nullable String name);
|
||||
|
||||
/**
|
||||
* Specifies the new color of the armored elytra.
|
||||
*
|
||||
* @param color The new color of the armored elytra. When this is null (default), the color to use is inferred
|
||||
* from the creation process.
|
||||
* @return The current builder step.
|
||||
*/
|
||||
IStep2 withColor(@Nullable Color color);
|
||||
|
||||
/**
|
||||
* Specifies the new lore of the armored elytra.
|
||||
*
|
||||
* @param lore The new lore of the armored elytra. When this is null (default), the default lore for the new
|
||||
* tier will be used.
|
||||
* @return The current builder step.
|
||||
*/
|
||||
IStep2 withLore(@Nullable List<String> lore);
|
||||
|
||||
/**
|
||||
* Specifies whether the armored elytra should be unbreakable.
|
||||
* <p>
|
||||
* By default, this value is read from {@link ConfigLoader#unbreakable()}.
|
||||
*
|
||||
* @param isUnbreakable True if the armored elytra should be unbreakable.
|
||||
* @return The current builder step.
|
||||
*/
|
||||
IStep2 unbreakable(boolean isUnbreakable);
|
||||
|
||||
/**
|
||||
* Constructs the armored elytra from the provided configuration.
|
||||
*
|
||||
* @return The new armored elytra.
|
||||
*/
|
||||
ItemStack build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the second and last step of the armored elytra build process.
|
||||
*/
|
||||
public interface IStep1
|
||||
{
|
||||
/**
|
||||
* Repairs the armored elytra provided as input.
|
||||
*
|
||||
* @param count The amount of repair items to process.
|
||||
* @return The next step of the builder process.
|
||||
*/
|
||||
IStep2 repair(int count);
|
||||
|
||||
/**
|
||||
* Adds a set of enchantments to the armored elytra.
|
||||
*
|
||||
* @param enchantmentContainer The enchantments to add.
|
||||
* @return The next step of the builder process.
|
||||
*/
|
||||
IStep2 addEnchantments(EnchantmentContainer enchantmentContainer);
|
||||
|
||||
/**
|
||||
* Adds a set of enchantments to the armored elytra.
|
||||
*
|
||||
* @param sourceItem The source item from which to take the enchantments.
|
||||
* @return The next step of the builder process.
|
||||
*/
|
||||
IStep2 addEnchantments(ItemStack sourceItem);
|
||||
|
||||
/**
|
||||
* Combines the input elytra with another item.
|
||||
*
|
||||
* @param item The item to combine with the input elytra. This can either be a chestplate or, if the input
|
||||
* elytra is an armored one, another armored elytra.
|
||||
* @param armorTier The armor tier of the input item. If this is not known, use {@link #combineWith(ItemStack)}
|
||||
* instead.
|
||||
* @return The next step of the builder process.
|
||||
*/
|
||||
IStep2 combineWith(ItemStack item, ArmorTier armorTier);
|
||||
|
||||
/**
|
||||
* See {@link #combineWith(ItemStack, ArmorTier)}. Used when the armor tier of the input item is not known.
|
||||
*
|
||||
* @return The next step of the builder process.
|
||||
*/
|
||||
IStep2 combineWith(ItemStack item);
|
||||
|
||||
/**
|
||||
* Upgrades the elytra to a specific armor tier.
|
||||
*
|
||||
* @param armorTier The new armor tier.
|
||||
* @return The next step of the builder process.
|
||||
*/
|
||||
IStep2 upgradeToTier(ArmorTier armorTier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the first and last step of the armored elytra build process.
|
||||
*/
|
||||
public interface IStep0
|
||||
{
|
||||
/**
|
||||
* Use an elytra as base item to create the new armored elytra from.
|
||||
*
|
||||
* @param elytra An itemstack that represents an elytra. It does not matter whether the elytra is armored or
|
||||
* not.
|
||||
* @return The next step of the builder process.
|
||||
*/
|
||||
IStep1 ofElytra(ItemStack elytra);
|
||||
|
||||
/**
|
||||
* Creates a fresh new armored elytra of a specific tier.
|
||||
*
|
||||
* @param armorTier The tier of the new armored elytra.
|
||||
* @return The next step of the builder process.
|
||||
*/
|
||||
IStep2 newItem(ArmorTier armorTier);
|
||||
}
|
||||
|
||||
private static final class Builder implements IStep0, IStep1, IStep2
|
||||
{
|
||||
private static final Color DEFAULT_LEATHER_COLOR = Bukkit.getServer().getItemFactory().getDefaultLeatherColor();
|
||||
|
||||
private final NBTEditor nbtEditor;
|
||||
private final DurabilityManager durabilityManager;
|
||||
private final ConfigLoader config;
|
||||
private final ArmoredElytra plugin;
|
||||
|
||||
// These aren't nullable, as they are set by the only entry points.
|
||||
/**
|
||||
* The new armored elytra that will be returned at the end of the build process.
|
||||
*/
|
||||
private ItemStack newArmoredElytra;
|
||||
/**
|
||||
* The combined enchantments of the input items.
|
||||
*/
|
||||
private EnchantmentContainer combinedEnchantments;
|
||||
/**
|
||||
* The current armor tier of the input elytra.
|
||||
*/
|
||||
private ArmorTier currentArmorTier;
|
||||
/**
|
||||
* The durability of the output armored elytra.
|
||||
*/
|
||||
private int durability;
|
||||
|
||||
|
||||
/**
|
||||
* The armor tier of the output armored elytra. This defaults to {@link #currentArmorTier} if this isn't set.
|
||||
*/
|
||||
private @Nullable ArmorTier newArmorTier;
|
||||
/**
|
||||
* The name of the output armored elytra. This defaults to {@link ArmoredElytra#getArmoredElytraName(ArmorTier)}
|
||||
* when not overridden.
|
||||
*/
|
||||
private @Nullable String name;
|
||||
/**
|
||||
* The lore of the output armored elytra. This defaults to {@link ArmoredElytra#getElytraLore(ArmorTier)} when
|
||||
* not overridden.
|
||||
*/
|
||||
private @Nullable List<String> lore;
|
||||
/**
|
||||
* The color of the output armored elytra. By default, the existing color (if any is used). When combined with
|
||||
* another item, the color is inferred using {@link #getItemColor(ItemStack, ItemStack)}.
|
||||
*/
|
||||
private @Nullable Color color;
|
||||
/**
|
||||
* Whether the output armored elytra should be unbreakable. This defaults to {@link ConfigLoader#unbreakable()}
|
||||
* when not overridden.
|
||||
*/
|
||||
private boolean isUnbreakable;
|
||||
|
||||
private Builder(NBTEditor nbtEditor, DurabilityManager durabilityManager,
|
||||
ConfigLoader config, ArmoredElytra plugin)
|
||||
{
|
||||
this.nbtEditor = nbtEditor;
|
||||
this.durabilityManager = durabilityManager;
|
||||
this.config = config;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack build()
|
||||
{
|
||||
// Get default values if unset.
|
||||
newArmorTier = newArmorTier == null ? currentArmorTier : newArmorTier;
|
||||
name = name == null ? plugin.getArmoredElytraName(newArmorTier) : name;
|
||||
lore = lore == null ? plugin.getElytraLore(newArmorTier) : lore;
|
||||
|
||||
final ItemStack output = nbtEditor.addArmorNBTTags(newArmoredElytra, newArmorTier,
|
||||
isUnbreakable, name, lore, color);
|
||||
durabilityManager.setDurability(output, durability, newArmorTier);
|
||||
combinedEnchantments.applyEnchantments(output);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStep2 withName(@Nullable String name)
|
||||
{
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStep2 withColor(@Nullable Color color)
|
||||
{
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStep2 withLore(@Nullable List<String> lore)
|
||||
{
|
||||
this.lore = lore;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStep2 unbreakable(boolean isUnbreakable)
|
||||
{
|
||||
this.isUnbreakable = isUnbreakable;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStep2 repair(int count)
|
||||
{
|
||||
if (currentArmorTier == ArmorTier.NONE)
|
||||
throw new IllegalArgumentException("Non-armored elytras cannot be repaired!");
|
||||
durabilityManager.getRepairedDurability(newArmoredElytra, count, currentArmorTier);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStep2 addEnchantments(EnchantmentContainer enchantmentContainer)
|
||||
{
|
||||
combinedEnchantments.merge(enchantmentContainer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStep2 addEnchantments(ItemStack sourceItem)
|
||||
{
|
||||
return addEnchantments(EnchantmentContainer.getEnchantments(sourceItem, plugin));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStep2 combineWith(ItemStack item, ArmorTier armorTier)
|
||||
{
|
||||
if (armorTier == ArmorTier.NONE && !Util.isChestPlate(item))
|
||||
throw new IllegalArgumentException("Non-armored elytras can only be combined with chest plates!");
|
||||
|
||||
newArmorTier = armorTier;
|
||||
if (currentArmorTier == ArmorTier.NONE &&
|
||||
item.getType().equals(Material.ELYTRA) && newArmorTier != ArmorTier.NONE)
|
||||
throw new IllegalArgumentException("A regular elytra cannot be combined with an armored one!");
|
||||
|
||||
withColor(getItemColor(newArmoredElytra, item));
|
||||
unbreakable(config.unbreakable());
|
||||
|
||||
addEnchantments(item);
|
||||
|
||||
durability = durabilityManager.getCombinedDurability(newArmoredElytra, item,
|
||||
currentArmorTier, newArmorTier);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStep2 combineWith(ItemStack item)
|
||||
{
|
||||
final ArmorTier armorTier = item.getType().equals(Material.ELYTRA) ?
|
||||
nbtEditor.getArmorTier(item) : Util.armorToTier(item.getType());
|
||||
return combineWith(item, armorTier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStep2 upgradeToTier(ArmorTier armorTier)
|
||||
{
|
||||
newArmorTier = armorTier;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStep1 ofElytra(ItemStack elytra)
|
||||
{
|
||||
if (!elytra.getType().equals(Material.ELYTRA))
|
||||
throw new IllegalArgumentException("Expected elytra as input, but got: " + elytra);
|
||||
|
||||
newArmoredElytra = new ItemStack(elytra);
|
||||
|
||||
if (currentArmorTier == null)
|
||||
currentArmorTier = nbtEditor.getArmorTier(elytra);
|
||||
|
||||
combinedEnchantments = EnchantmentContainer.getEnchantments(newArmoredElytra, plugin);
|
||||
|
||||
durability = durabilityManager.getRealDurability(newArmoredElytra, currentArmorTier);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStep2 newItem(ArmorTier armorTier)
|
||||
{
|
||||
currentArmorTier = newArmorTier = armorTier;
|
||||
ofElytra(new ItemStack(Material.ELYTRA));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the color of the item if the item has a color.
|
||||
* <p>
|
||||
* See {@link LeatherArmorMeta#getColor()}.
|
||||
*
|
||||
* @param itemA The first {@link ItemStack} to check.
|
||||
* @param itemB The second {@link ItemStack} to check.
|
||||
* @return The color of the item, if it has a color, otherwise null.
|
||||
*/
|
||||
private @Nullable Color getItemColor(final ItemStack itemA, final ItemStack itemB)
|
||||
{
|
||||
final @Nullable Color colorA = getItemColor(itemA);
|
||||
if (colorA != null && !colorA.equals(DEFAULT_LEATHER_COLOR))
|
||||
return colorA;
|
||||
|
||||
final @Nullable Color colorB = getItemColor(itemB);
|
||||
return colorB != null ? colorB : colorA;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the colors of an item if available.
|
||||
* <p>
|
||||
* This currently only applies to leather armor(ed elytras).
|
||||
*
|
||||
* @param itemStack The item to analyze.
|
||||
* @return The color of the item, if available, otherwise null.
|
||||
*/
|
||||
private @Nullable Color getItemColor(final ItemStack itemStack)
|
||||
{
|
||||
if (itemStack.getType() == Material.ELYTRA)
|
||||
return nbtEditor.getColorOfArmoredElytra(itemStack);
|
||||
|
||||
if (!itemStack.hasItemMeta() || !(itemStack.getItemMeta() instanceof LeatherArmorMeta))
|
||||
return null;
|
||||
|
||||
return ((LeatherArmorMeta) itemStack.getItemMeta()).getColor();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
package nl.pim16aap2.armoredElytra.util;
|
||||
package nl.pim16aap2.armoredElytra.nbtEditor;
|
||||
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
|
||||
import nl.pim16aap2.armoredElytra.util.ArmorTier;
|
||||
import nl.pim16aap2.armoredElytra.util.ConfigLoader;
|
||||
import nl.pim16aap2.armoredElytra.util.Util;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
@ -118,7 +118,7 @@ public class NBTEditor
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void overwriteNBTValue(ItemMeta meta, Attribute attribute, double value, String modifierName)
|
||||
void overwriteNBTValue(ItemMeta meta, Attribute attribute, double value, String modifierName)
|
||||
{
|
||||
if (meta.hasAttributeModifiers())
|
||||
meta.removeAttributeModifier(attribute);
|
||||
@ -129,7 +129,7 @@ public class NBTEditor
|
||||
meta.addAttributeModifier(attribute, attributeModifier);
|
||||
}
|
||||
|
||||
private ArmorTier getArmorTier(@Nullable ItemMeta meta)
|
||||
ArmorTier getArmorTier(@Nullable ItemMeta meta)
|
||||
{
|
||||
if (meta == null || !meta.hasAttributeModifiers())
|
||||
return ArmorTier.NONE;
|
||||
@ -191,7 +191,7 @@ public class NBTEditor
|
||||
return rgb == null ? null : Color.fromRGB(rgb);
|
||||
}
|
||||
|
||||
private static ItemMeta getOrCreateItemMeta(ItemStack item)
|
||||
static ItemMeta getOrCreateItemMeta(ItemStack item)
|
||||
{
|
||||
final ItemMeta meta = item.hasItemMeta() ?
|
||||
item.getItemMeta() :
|
||||
@ -200,71 +200,4 @@ public class NBTEditor
|
||||
throw new IllegalArgumentException("Tried to add armor to invalid item: " + item);
|
||||
return meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a given {@link ArmorTier} to an item. The item will be cloned. Note that setting the armor tier to {@link
|
||||
* ArmorTier#NONE} has no effect (besides making a copy of the item). The default name for the given tier is
|
||||
* applied. See {@link ArmoredElytra#getArmoredElytraName(ArmorTier)}.
|
||||
*
|
||||
* @param item The item.
|
||||
* @param armorTier The {@link ArmorTier} that will be added to it.
|
||||
* @param unbreakable Whether the resulting item should be unbreakable.
|
||||
* @return The NEW item.
|
||||
*/
|
||||
public ItemStack addArmorNBTTags(ItemStack item, ArmorTier armorTier, boolean unbreakable)
|
||||
{
|
||||
return addArmorNBTTags(item, armorTier, unbreakable, (Color) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a given {@link ArmorTier} to an item. The item will be cloned. Note that setting the armor tier to {@link
|
||||
* ArmorTier#NONE} has no effect (besides making a copy of the item).
|
||||
*
|
||||
* @param item The item.
|
||||
* @param armorTier The {@link ArmorTier} that will be added to it.
|
||||
* @param unbreakable Whether the resulting item should be unbreakable.
|
||||
* @param name The name fo the item.
|
||||
* @return The NEW item.
|
||||
*/
|
||||
public ItemStack addArmorNBTTags(ItemStack item, ArmorTier armorTier, boolean unbreakable, final String name)
|
||||
{
|
||||
return addArmorNBTTags(item, armorTier, unbreakable, name, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a given {@link ArmorTier} to an item. The item will be cloned. Note that setting the armor tier to {@link
|
||||
* ArmorTier#NONE} has no effect (besides making a copy of the item). The default name for the given tier is
|
||||
* applied. See {@link ArmoredElytra#getArmoredElytraName(ArmorTier)}.
|
||||
*
|
||||
* @param item The item.
|
||||
* @param armorTier The {@link ArmorTier} that will be added to it.
|
||||
* @param unbreakable Whether the resulting item should be unbreakable.
|
||||
* @param color The color of the armor to store. May be null.
|
||||
* @return The NEW item.
|
||||
*/
|
||||
public ItemStack addArmorNBTTags(ItemStack item, ArmorTier armorTier, boolean unbreakable, final Color color)
|
||||
{
|
||||
return addArmorNBTTags(item, armorTier, unbreakable,
|
||||
ArmoredElytra.getInstance().getArmoredElytraName(armorTier),
|
||||
ArmoredElytra.getInstance().getElytraLore(armorTier), color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a given {@link ArmorTier} to an item. The item will be cloned. Note that setting the armor tier to {@link
|
||||
* ArmorTier#NONE} has no effect (besides making a copy of the item). The default name for the given tier is
|
||||
* applied. See {@link ArmoredElytra#getArmoredElytraName(ArmorTier)}.
|
||||
*
|
||||
* @param item The item.
|
||||
* @param armorTier The {@link ArmorTier} that will be added to it.
|
||||
* @param unbreakable Whether the resulting item should be unbreakable.
|
||||
* @param name The name of the item.
|
||||
* @param color The color of the armor to store. May be null.
|
||||
* @return The NEW item.
|
||||
*/
|
||||
public ItemStack addArmorNBTTags(ItemStack item, ArmorTier armorTier, boolean unbreakable, String name,
|
||||
Color color)
|
||||
{
|
||||
return addArmorNBTTags(item, armorTier, unbreakable, name,
|
||||
ArmoredElytra.getInstance().getElytraLore(armorTier), color);
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,19 @@ public class EnchantmentContainer
|
||||
filter(plugin.getConfigLoader().allowedEnchantments());
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
*/
|
||||
public EnchantmentContainer(EnchantmentContainer other)
|
||||
{
|
||||
this(other.enchantments);
|
||||
}
|
||||
|
||||
public EnchantmentContainer()
|
||||
{
|
||||
enchantments = new HashMap<>();
|
||||
}
|
||||
|
||||
private EnchantmentContainer(final Map<Enchantment, Integer> enchantments)
|
||||
{
|
||||
this.enchantments = new HashMap<>(enchantments);
|
||||
@ -117,6 +130,8 @@ public class EnchantmentContainer
|
||||
*/
|
||||
public void merge(EnchantmentContainer other)
|
||||
{
|
||||
if (this == other)
|
||||
throw new IllegalArgumentException("EnchantmentContainers cannot be combined with themselves!");
|
||||
enchantments = merge(enchantments, other.enchantments);
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,12 @@ public class Util
|
||||
return item.getDurability() >= item.getType().getMaxDurability();
|
||||
}
|
||||
|
||||
// Get the armor tier from a chest plate.
|
||||
public static ArmorTier armorToTier(ItemStack itemStack)
|
||||
{
|
||||
return armorToTier(itemStack.getType());
|
||||
}
|
||||
|
||||
// Get the armor tier from a chest plate.
|
||||
public static ArmorTier armorToTier(Material mat)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user