diff --git a/src/main/java/nl/pim16aap2/armoredElytra/ArmoredElytra.java b/src/main/java/nl/pim16aap2/armoredElytra/ArmoredElytra.java index 8d3116c..0ef4d1b 100644 --- a/src/main/java/nl/pim16aap2/armoredElytra/ArmoredElytra.java +++ b/src/main/java/nl/pim16aap2/armoredElytra/ArmoredElytra.java @@ -50,6 +50,7 @@ public class ArmoredElytra extends JavaPlugin implements Listener private UpdateManager updateManager; private INBTEditor nbtEditor; + private DurabilityManager durabilityManager; @Override public void onEnable() @@ -75,6 +76,9 @@ public class ArmoredElytra extends JavaPlugin implements Listener nbtEditor = new NBTEditor(); config = new ConfigLoader(this); + + durabilityManager = new DurabilityManager(nbtEditor, config); + messages = new Messages(this); readMessages(); @@ -94,29 +98,26 @@ public class ArmoredElytra extends JavaPlugin implements Listener "Stats disabled, not loading stats :(... Please consider enabling it! I am a simple man, " + "seeing higher user numbers helps me stay motivated!"); - Bukkit.getPluginManager().registerEvents(new EventHandlers(this), this); - getCommand("ArmoredElytra").setExecutor(new CommandHandler(this)); + Bukkit.getPluginManager().registerEvents(new EventHandlers(this, nbtEditor, durabilityManager), this); + getCommand("ArmoredElytra").setExecutor(new CommandHandler(this, nbtEditor, durabilityManager)); // Load the plugin normally if not in uninstall mode. if (!config.uninstallMode()) { - // Check if the user wants to disable durability penalty for flying with an armored elytra. - if (config.noFlightDurability()) - { - Bukkit.getPluginManager().registerEvents(new FlyDurabilityHandler(), this); - myLogger(Level.INFO, "Durability penalty for flying disabled!"); - } - else - myLogger(Level.INFO, "Durability penalty for flying enabled!"); + Bukkit.getPluginManager().registerEvents(new FlyDurabilityHandler(config.noFlightDurability(), + nbtEditor, durabilityManager), this); + final Listener creationListener = + config.craftingInSmithingTable() ? + new SmithingTableCraftHandler(this, nbtEditor, durabilityManager, config) : + new AnvilHandler(this, nbtEditor, durabilityManager, config); - final Listener creationListener = config.craftingInSmithingTable() ? - new SmithingTableCraftHandler(this) : new AnvilHandler(this); Bukkit.getPluginManager().registerEvents(creationListener, this); if (config.allowUpgradeToNetherite()) - Bukkit.getPluginManager().registerEvents(new NetheriteUpgradeListener(this), this); + Bukkit.getPluginManager() + .registerEvents(new NetheriteUpgradeListener(this, nbtEditor, durabilityManager, config), this); if (config.dropNetheriteAsChestplate()) - Bukkit.getPluginManager().registerEvents(new ItemDropListener(this), this); + Bukkit.getPluginManager().registerEvents(new ItemDropListener(nbtEditor), this); // Log all allowed enchantments. myLogger(Level.INFO, ("Allowed enchantments:")); @@ -126,7 +127,7 @@ public class ArmoredElytra extends JavaPlugin implements Listener else { myLogger(Level.WARNING, "Plugin in uninstall mode!"); - Bukkit.getPluginManager().registerEvents(new Uninstaller(this), this); + Bukkit.getPluginManager().registerEvents(new Uninstaller(this, nbtEditor), this); } } diff --git a/src/main/java/nl/pim16aap2/armoredElytra/DurabilityManager.java b/src/main/java/nl/pim16aap2/armoredElytra/DurabilityManager.java index 604cc1c..710c091 100644 --- a/src/main/java/nl/pim16aap2/armoredElytra/DurabilityManager.java +++ b/src/main/java/nl/pim16aap2/armoredElytra/DurabilityManager.java @@ -13,7 +13,7 @@ public class DurabilityManager { private static final int ELYTRA_MAX_DURABILITY = Material.ELYTRA.getMaxDurability(); - private final int[] repairSteps = new int[ArmorTier.values().length]; + private final int[] repairAmounts = new int[ArmorTier.values().length]; private final int[] maxDurabilities = new int[ArmorTier.values().length]; private final INBTEditor nbtEditor; @@ -26,6 +26,28 @@ public class DurabilityManager init(); } + /** + * Combination of {@link #getCombinedDurability(ItemStack, ItemStack, ArmorTier, ArmorTier)} and {@link + * #setDurability(ItemStack, int, ArmorTier)}. + *
+ * First gets the combined of the input armored elytra and the other item and then applies it to the target armored
+ * elytra.
+ *
+ * @param armoredElytraOut The output armored elytra item. This is the elytra that will be updated.
+ * @param armoredElytraIn The input armored elytra item.
+ * @param other The other item that will be combined with the armored elytra. This can be another armored
+ * elytra, a chestplate, or any other item.
+ * @param currentTier The current armor tier of the armored elytra.
+ * @param targetTier The target tier of the armored elytra.
+ */
+ public int setCombinedDurability(ItemStack armoredElytraOut, ItemStack armoredElytraIn, ItemStack other,
+ ArmorTier currentTier, ArmorTier targetTier)
+ {
+ final int combinedDurability = getCombinedDurability(armoredElytraIn, other, currentTier, targetTier);
+ setDurability(armoredElytraOut, combinedDurability, targetTier);
+ return combinedDurability;
+ }
+
/**
* Gets durability value resulting from combining an armored elytra with some other item with durability.
*
@@ -43,17 +65,36 @@ public class DurabilityManager
final int currentMaxDurability = getMaxDurability(currentTier);
final int targetMaxDurability = getMaxDurability(targetTier);
- final int otherMaxDurability = otherTier == ArmorTier.NONE ?
- other.getType().getMaxDurability() : getMaxDurability(otherTier);
-
+ final int otherMaxDurability = otherTier != ArmorTier.NONE ?
+ getMaxDurability(otherTier) : other.getType().getMaxDurability();
+ //noinspection deprecation
final int otherDurability = other.getType().equals(Material.ELYTRA) ?
- getRealDurability(other, null) : other.getType().getMaxDurability();
-
+ getRealDurability(other, null) : other.getDurability();
final int currentDurability = getRealDurability(armoredElytra, currentTier);
- return targetMaxDurability -
+ final int combinedDurability = targetMaxDurability -
(otherMaxDurability - otherDurability) -
(currentMaxDurability - currentDurability);
+
+ return Util.between(combinedDurability, 0, targetMaxDurability);
+ }
+
+ /**
+ * Removes durability from an armored elytra.
+ *
+ * @param armoredElytra The armored elytra item to damage.
+ * @param durabilityLoss The amount of durability to remove from the armored elytra.
+ * @param providedTier The tier of the armored elytra (if this is available). If this is null, it will be
+ * retrieved from the item itself.
+ * @return The new durability after removing the provided amount.
+ */
+ public int removeDurability(ItemStack armoredElytra, int durabilityLoss, @Nullable ArmorTier providedTier)
+ {
+ final ArmorTier currentTier = providedTier == null ? nbtEditor.getArmorTier(armoredElytra) : providedTier;
+ final int currentDurability = getRealDurability(armoredElytra, currentTier);
+ final int newDurability = Util.between(currentDurability + durabilityLoss, 0, getMaxDurability(currentTier));
+ setDurability(armoredElytra, newDurability, providedTier);
+ return newDurability;
}
/**
@@ -71,7 +112,7 @@ public class DurabilityManager
{
final ArmorTier currentTier = providedTier == null ? nbtEditor.getArmorTier(armoredElytra) : providedTier;
final int repairableDurability = getMaxDurability(currentTier) - getRealDurability(armoredElytra, currentTier);
- return (int) Math.ceil((float) repairableDurability / getRepairSteps(currentTier));
+ return (int) Math.ceil((float) repairableDurability / getRepairAmount(currentTier));
}
/**
@@ -87,7 +128,7 @@ public class DurabilityManager
public int getRepairedDurability(ItemStack armoredElytra, int repairCount, @Nullable ArmorTier providedTier)
{
final ArmorTier currentTier = providedTier == null ? nbtEditor.getArmorTier(armoredElytra) : providedTier;
- final int restoredDurability = repairCount * getRepairSteps(currentTier);
+ final int restoredDurability = repairCount * getRepairAmount(currentTier);
final int currentDurability = getRealDurability(armoredElytra, currentTier);
return Math.max(0, currentDurability - restoredDurability);
}
@@ -125,8 +166,8 @@ public class DurabilityManager
public void setDurability(ItemStack item, int durability, @Nullable ArmorTier providedTier)
{
final ArmorTier currentTier = providedTier == null ? nbtEditor.getArmorTier(item) : providedTier;
- final int rawDurability = getRemappedDurability(durability, getMaxDurability(currentTier),
- ELYTRA_MAX_DURABILITY);
+ final int oldMaxDurability = getMaxDurability(currentTier);
+ final int rawDurability = getRemappedDurability(durability, oldMaxDurability, ELYTRA_MAX_DURABILITY);
nbtEditor.updateDurability(item, durability, rawDurability);
}
@@ -174,7 +215,7 @@ public class DurabilityManager
* @param armorTier The armor tier for which to get the maximum durability.
* @return The maximum durability of the given armor tier.
*/
- private int getMaxDurability(ArmorTier armorTier)
+ public int getMaxDurability(ArmorTier armorTier)
{
return maxDurabilities[armorTier.ordinal()];
}
@@ -185,9 +226,9 @@ public class DurabilityManager
* @param armorTier The armor tier.
* @return The amount of durability restored per repair step for the given armor tier.
*/
- private int getRepairSteps(ArmorTier armorTier)
+ public int getRepairAmount(ArmorTier armorTier)
{
- return repairSteps[armorTier.ordinal()];
+ return repairAmounts[armorTier.ordinal()];
}
/**
@@ -207,11 +248,11 @@ public class DurabilityManager
}
/**
- * Initializes the {@link #maxDurabilities} and {@link #repairSteps} arrays.
+ * Initializes the {@link #maxDurabilities} and {@link #repairAmounts} arrays.
*/
private void init()
{
- repairSteps[0] = 0;
+ repairAmounts[0] = 0;
maxDurabilities[0] = ELYTRA_MAX_DURABILITY;
final ArmorTier[] armorTiers = ArmorTier.values();
@@ -223,7 +264,7 @@ public class DurabilityManager
maxDurabilities[idx] = maxDurability;
final int steps = Math.max(1, config.getFullRepairItemCount(armorTier));
- repairSteps[idx] = (int) Math.ceil((float) maxDurability / steps);
+ repairAmounts[idx] = (int) Math.ceil((float) maxDurability / steps);
}
}
}
diff --git a/src/main/java/nl/pim16aap2/armoredElytra/handlers/AnvilHandler.java b/src/main/java/nl/pim16aap2/armoredElytra/handlers/AnvilHandler.java
index 2312632..f26ff8b 100644
--- a/src/main/java/nl/pim16aap2/armoredElytra/handlers/AnvilHandler.java
+++ b/src/main/java/nl/pim16aap2/armoredElytra/handlers/AnvilHandler.java
@@ -27,21 +27,16 @@ import java.util.logging.Level;
public class AnvilHandler extends ArmoredElytraHandler implements Listener
{
- private final ConfigLoader configLoader;
- private final INBTEditor nbtEditor;
- private final DurabilityManager durabilityManager;
-
- public AnvilHandler(final ArmoredElytra plugin, final boolean creationEnabled)
+ protected AnvilHandler(ArmoredElytra plugin, boolean creationEnabled,
+ INBTEditor nbtEditor, DurabilityManager durabilityManager, ConfigLoader config)
{
- super(plugin, creationEnabled);
- configLoader = plugin.getConfigLoader();
- nbtEditor = plugin.getNbtEditor();
- durabilityManager = new DurabilityManager(nbtEditor, configLoader);
+ super(plugin, creationEnabled, nbtEditor, durabilityManager, config);
}
- public AnvilHandler(final ArmoredElytra plugin)
+ public AnvilHandler(ArmoredElytra plugin, INBTEditor nbtEditor,
+ DurabilityManager durabilityManager, ConfigLoader config)
{
- this(plugin, true);
+ super(plugin, true, nbtEditor, durabilityManager, config);
}
// Valid inputs:
@@ -74,11 +69,11 @@ public class AnvilHandler extends ArmoredElytraHandler implements Listener
{
// If the armored elytra is to be enchanted using an enchanted book...
if (matTwo == Material.ENCHANTED_BOOK)
- return configLoader.allowAddingEnchantments() ? Action.ENCHANT : Action.BLOCK;
+ 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 itemOne.getDurability() == 0 ? Action.BLOCK : Action.REPAIR;
+ return durabilityManager.getRealDurability(itemOne, tier) == 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)
@@ -120,7 +115,7 @@ public class AnvilHandler extends ArmoredElytraHandler implements Listener
final ArmorTier curTier = nbtEditor.getArmorTier(itemA);
int newDurability = 0;
- EnchantmentContainer enchantments = EnchantmentContainer.getEnchantments(itemA, plugin);
+ final EnchantmentContainer enchantments = EnchantmentContainer.getEnchantments(itemA, plugin);
switch (action)
{
@@ -168,7 +163,7 @@ public class AnvilHandler extends ArmoredElytraHandler implements Listener
final String name = getElytraResultName(itemA, action, newTier, event.getInventory().getRenameText());
final Color color = getItemColor(itemA, itemB);
- result = nbtEditor.addArmorNBTTags(result, newTier, configLoader.unbreakable(), name, color);
+ result = nbtEditor.addArmorNBTTags(result, newTier, config.unbreakable(), name, color);
event.setResult(result);
return;
@@ -186,13 +181,13 @@ public class AnvilHandler extends ArmoredElytraHandler implements Listener
final ArmorTier armorTier, final String renameText)
{
final String tierName = plugin.getArmoredElytraName(armorTier);
- if (renameText == null || !configLoader.allowRenaming())
+ if (renameText == null || !config.allowRenaming())
return tierName;
final ItemMeta meta = baseItem.getItemMeta();
final String currentName = meta == null ? null : meta.getDisplayName();
- // When the rename text is empty, give it the default tier-name when creating a new armored elytra
+ // When the renameText is empty, give it the default tier-name when creating a new armored elytra
// (so it's named properly) or when the current name is already the tier name (just returning the current
// name would strip the tier's color in this case).
if ((action == Action.CREATE && renameText.equals("")) ||
diff --git a/src/main/java/nl/pim16aap2/armoredElytra/handlers/ArmoredElytraHandler.java b/src/main/java/nl/pim16aap2/armoredElytra/handlers/ArmoredElytraHandler.java
index 73cb30e..d7d2717 100644
--- a/src/main/java/nl/pim16aap2/armoredElytra/handlers/ArmoredElytraHandler.java
+++ b/src/main/java/nl/pim16aap2/armoredElytra/handlers/ArmoredElytraHandler.java
@@ -1,9 +1,9 @@
package nl.pim16aap2.armoredElytra.handlers;
import nl.pim16aap2.armoredElytra.ArmoredElytra;
-import nl.pim16aap2.armoredElytra.util.ArmorTier;
+import nl.pim16aap2.armoredElytra.DurabilityManager;
+import nl.pim16aap2.armoredElytra.nbtEditor.INBTEditor;
import nl.pim16aap2.armoredElytra.util.ConfigLoader;
-import nl.pim16aap2.armoredElytra.util.XMaterial;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.Material;
@@ -24,38 +24,18 @@ abstract class ArmoredElytraHandler
protected final ArmoredElytra plugin;
protected final boolean creationEnabled;
- private final ConfigLoader config;
+ protected final ConfigLoader config;
+ protected final INBTEditor nbtEditor;
+ protected final DurabilityManager durabilityManager;
- public ArmoredElytraHandler(final ArmoredElytra plugin, final boolean creationEnabled)
+ protected ArmoredElytraHandler(ArmoredElytra plugin, boolean creationEnabled, INBTEditor nbtEditor,
+ DurabilityManager durabilityManager, ConfigLoader config)
{
this.plugin = plugin;
this.creationEnabled = creationEnabled;
- config = plugin.getConfigLoader();
- }
-
- // Repair an Armored Elytra
- protected short repairItem(short curDur, ItemStack repairItem)
- {
- final ArmorTier repairTier;
- if (repairItem.getType().equals(Material.LEATHER))
- repairTier = ArmorTier.LEATHER;
- else if (repairItem.getType().equals(Material.GOLD_INGOT))
- repairTier = ArmorTier.GOLD;
- else if (repairItem.getType().equals(Material.IRON_INGOT))
- repairTier = ArmorTier.IRON;
- else if (repairItem.getType().equals(Material.DIAMOND))
- repairTier = ArmorTier.DIAMOND;
- else if (repairItem.getType().equals(XMaterial.NETHERITE_INGOT.parseMaterial()))
- repairTier = ArmorTier.NETHERITE;
- else
- repairTier = ArmorTier.NONE;
-
- final int repairCount = Math.max(1, config.getFullRepairItemCount(repairTier));
- final double repairPercentage = 1f / repairCount;
-
- int maxDurability = Material.ELYTRA.getMaxDurability();
- int newDurability = (int) (curDur - repairItem.getAmount() * (maxDurability * repairPercentage));
- return (short) (Math.max(newDurability, 0));
+ this.nbtEditor = nbtEditor;
+ this.durabilityManager = durabilityManager;
+ this.config = config;
}
/**
@@ -83,7 +63,7 @@ abstract class ArmoredElytraHandler
return null;
if (itemStack.getType() == Material.ELYTRA)
- return ArmoredElytra.getInstance().getNbtEditor().getColorOfArmoredElytra(itemStack);
+ return nbtEditor.getColorOfArmoredElytra(itemStack);
if (!itemStack.hasItemMeta() || !(itemStack.getItemMeta() instanceof LeatherArmorMeta))
return null;
diff --git a/src/main/java/nl/pim16aap2/armoredElytra/handlers/CommandHandler.java b/src/main/java/nl/pim16aap2/armoredElytra/handlers/CommandHandler.java
index e18b1ce..1bf165e 100644
--- a/src/main/java/nl/pim16aap2/armoredElytra/handlers/CommandHandler.java
+++ b/src/main/java/nl/pim16aap2/armoredElytra/handlers/CommandHandler.java
@@ -1,6 +1,8 @@
package nl.pim16aap2.armoredElytra.handlers;
import nl.pim16aap2.armoredElytra.ArmoredElytra;
+import nl.pim16aap2.armoredElytra.DurabilityManager;
+import nl.pim16aap2.armoredElytra.nbtEditor.INBTEditor;
import nl.pim16aap2.armoredElytra.util.ArmorTier;
import nl.pim16aap2.armoredElytra.util.messages.Message;
import org.bukkit.Bukkit;
@@ -21,11 +23,15 @@ import java.util.logging.Level;
public class CommandHandler implements CommandExecutor
{
private final ArmoredElytra plugin;
+ private final INBTEditor nbtEditor;
+ private final DurabilityManager durabilityManager;
private static Field BY_KEY_FIELD;
- public CommandHandler(ArmoredElytra plugin)
+ public CommandHandler(ArmoredElytra plugin, INBTEditor nbtEditor, DurabilityManager durabilityManager)
{
this.plugin = plugin;
+ this.nbtEditor = nbtEditor;
+ this.durabilityManager = durabilityManager;
}
@Override
@@ -80,9 +86,9 @@ public class CommandHandler implements CommandExecutor
if (allowed)
{
plugin.elytraReceivedMessage(receiver, armorTier);
- newElytra = ArmoredElytra.getInstance().getNbtEditor()
- .addArmorNBTTags(new ItemStack(Material.ELYTRA, 1), armorTier,
- plugin.getConfigLoader().unbreakable());
+ newElytra = nbtEditor.addArmorNBTTags(new ItemStack(Material.ELYTRA, 1), armorTier,
+ plugin.getConfigLoader().unbreakable());
+ durabilityManager.setDurability(newElytra, 0, armorTier);
plugin.giveArmoredElytraToPlayer(receiver, newElytra);
}
else
@@ -119,9 +125,10 @@ public class CommandHandler implements CommandExecutor
return false;
plugin.elytraReceivedMessage(player, armorTier);
- newElytra = ArmoredElytra.getInstance().getNbtEditor()
- .addArmorNBTTags(new ItemStack(Material.ELYTRA, 1), armorTier,
- plugin.getConfigLoader().unbreakable());
+ newElytra = nbtEditor.addArmorNBTTags(new ItemStack(Material.ELYTRA, 1), armorTier,
+ plugin.getConfigLoader().unbreakable());
+ durabilityManager.setDurability(newElytra, 0, armorTier);
+
plugin.giveArmoredElytraToPlayer(player, newElytra);
plugin.myLogger(Level.INFO, ("Giving an armored elytra of the " + ArmorTier.getArmor(armorTier) +
" armor tier to player " + player.getName()));
diff --git a/src/main/java/nl/pim16aap2/armoredElytra/handlers/EventHandlers.java b/src/main/java/nl/pim16aap2/armoredElytra/handlers/EventHandlers.java
index ae4fd51..1340949 100644
--- a/src/main/java/nl/pim16aap2/armoredElytra/handlers/EventHandlers.java
+++ b/src/main/java/nl/pim16aap2/armoredElytra/handlers/EventHandlers.java
@@ -1,10 +1,12 @@
package nl.pim16aap2.armoredElytra.handlers;
import nl.pim16aap2.armoredElytra.ArmoredElytra;
+import nl.pim16aap2.armoredElytra.DurabilityManager;
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.INBTEditor;
import nl.pim16aap2.armoredElytra.util.AllowedToWearEnum;
import nl.pim16aap2.armoredElytra.util.ArmorTier;
import nl.pim16aap2.armoredElytra.util.Util;
@@ -14,6 +16,7 @@ import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
@@ -24,12 +27,16 @@ import java.util.Random;
public class EventHandlers implements Listener
{
- private final ArmoredElytra plugin;
private final Random random = new Random();
+ private final ArmoredElytra plugin;
+ private final INBTEditor nbtEditor;
+ private final DurabilityManager durabilityManager;
- public EventHandlers(ArmoredElytra plugin)
+ public EventHandlers(ArmoredElytra plugin, INBTEditor nbtEditor, DurabilityManager durabilityManager)
{
this.plugin = plugin;
+ this.nbtEditor = nbtEditor;
+ this.durabilityManager = durabilityManager;
initializeArmorEquipEvent();
}
@@ -39,13 +46,6 @@ public class EventHandlers implements Listener
Bukkit.getPluginManager().registerEvents(new DispenserArmorListener(), plugin);
}
- private void moveChestplateToInventory(Player player)
- {
- player.getInventory().addItem(player.getInventory().getChestplate());
- player.getInventory().getChestplate().setAmount(0);
- player.updateInventory();
- }
-
// Make sure the player has the correct permission and that the item is not
// broken.
private AllowedToWearEnum isAllowedToWear(ItemStack elytra, Player player, ArmorTier armorTier)
@@ -60,62 +60,44 @@ public class EventHandlers implements Listener
}
// Handle armored elytra durability loss.
- @EventHandler(ignoreCancelled = true)
+ @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerDamage(EntityDamageEvent e)
{
if (!(e.getEntity() instanceof Player))
return;
+ final Player p = (Player) e.getEntity();
- if (plugin.getConfigLoader().unbreakable())
+ final ItemStack elytra = p.getInventory().getChestplate();
+ if (elytra == null)
return;
- Player p = (Player) e.getEntity();
- // If the player didn't die from the damage.
- if ((p.getHealth() - e.getFinalDamage()) > 0)
+ final ArmorTier armorTier = nbtEditor.getArmorTier(elytra);
+ if (armorTier == ArmorTier.NONE)
+ return;
+
+ final DamageCause cause = e.getCause();
+ // The elytra doesn't receive any damage for these causes:
+ if (cause == DamageCause.DROWNING || cause == DamageCause.STARVATION || cause == DamageCause.SUFFOCATION ||
+ cause == DamageCause.SUICIDE || cause == DamageCause.FLY_INTO_WALL || cause == DamageCause.POISON)
+ return;
+
+ final boolean removeDurability;
+ if (elytra.containsEnchantment(Enchantment.DURABILITY))
{
- if (p.getInventory().getChestplate() == null)
- return;
-
- if (ArmoredElytra.getInstance().getNbtEditor().getArmorTier(p.getInventory().getChestplate()) ==
- ArmorTier.NONE)
- return;
-
- ItemStack elytra = p.getInventory().getChestplate();
- DamageCause cause = e.getCause();
-
- // The elytra doesn't receive any damage for these causes:
- if (cause != DamageCause.DROWNING && cause != DamageCause.STARVATION && cause != DamageCause.SUFFOCATION &&
- cause != DamageCause.SUICIDE && cause != DamageCause.FLY_INTO_WALL && cause != DamageCause.POISON)
- {
- int durability = p.getInventory().getChestplate().getDurability();
- int maxDurability = p.getInventory().getChestplate().getType().getMaxDurability();
- int newDurability = durability + ((int) (e.getDamage() / 4) > 1 ? (int) (e.getDamage() / 4) : 1);
-
- // If the elytra has the durability enchantment, we calculate the durability
- // loss ourselves.
- if (p.getInventory().getChestplate().containsEnchantment(Enchantment.DURABILITY))
- {
- // Get a random int between 0 and 100 to use in deciding if the durability
- // enchantment will take effect.
- int randomInt = random.nextInt(101);
- int enchantLevel = p.getInventory().getChestplate().getEnchantmentLevel(Enchantment.DURABILITY);
- int durabilityDelta = (100 / (enchantLevel + 1)) < randomInt ? 0 : 1;
- // If the durability equals/exceeds maxDurability, it's broken (0 = full item
- // durability).
- if (durability >= maxDurability)
- moveChestplateToInventory(p);
- else
- newDurability = durability + durabilityDelta;
- }
- // If the item should be broken, make sure it really is broken and unequip it.
- if (newDurability >= maxDurability)
- {
- newDurability = maxDurability;
- moveChestplateToInventory(p);
- }
- elytra.setDurability((short) (newDurability));
- }
+ final int randomInt = random.nextInt(101);
+ final int enchantLevel = elytra.getEnchantmentLevel(Enchantment.DURABILITY);
+ // Formula taken from: https://minecraft.fandom.com/wiki/Unbreaking#Usage
+ final float removeDurabilityChance = 60 + 40f / (enchantLevel + 1);
+ removeDurability = randomInt <= removeDurabilityChance;
}
+ else
+ removeDurability = true;
+
+ // Even when we don't subtract durability, we still want to update the durability, so just subtract 0.
+ final int durabilityLoss = removeDurability ? (int) Math.max(1, e.getDamage() / 4) : 0;
+ final int newDurability = durabilityManager.removeDurability(elytra, durabilityLoss, armorTier);
+ if (newDurability >= durabilityManager.getMaxDurability(armorTier))
+ Util.moveChestplateToInventory(p);
}
@EventHandler
@@ -130,8 +112,8 @@ public class EventHandlers implements Listener
!e.getNewArmorPiece().getType().equals(Material.ELYTRA))
return;
- ArmorTier armorTier = ArmoredElytra.getInstance().getNbtEditor().getArmorTier(e.getNewArmorPiece());
- AllowedToWearEnum allowed = isAllowedToWear(e.getNewArmorPiece(), e.getPlayer(), armorTier);
+ final ArmorTier armorTier = nbtEditor.getArmorTier(e.getNewArmorPiece());
+ final AllowedToWearEnum allowed = isAllowedToWear(e.getNewArmorPiece(), e.getPlayer(), armorTier);
switch (allowed)
{
case ALLOWED:
diff --git a/src/main/java/nl/pim16aap2/armoredElytra/handlers/FlyDurabilityHandler.java b/src/main/java/nl/pim16aap2/armoredElytra/handlers/FlyDurabilityHandler.java
index 79fe0f8..250fbd0 100644
--- a/src/main/java/nl/pim16aap2/armoredElytra/handlers/FlyDurabilityHandler.java
+++ b/src/main/java/nl/pim16aap2/armoredElytra/handlers/FlyDurabilityHandler.java
@@ -1,21 +1,30 @@
package nl.pim16aap2.armoredElytra.handlers;
-import nl.pim16aap2.armoredElytra.ArmoredElytra;
+import nl.pim16aap2.armoredElytra.DurabilityManager;
+import nl.pim16aap2.armoredElytra.nbtEditor.INBTEditor;
import nl.pim16aap2.armoredElytra.util.ArmorTier;
+import nl.pim16aap2.armoredElytra.util.Util;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerItemDamageEvent;
public class FlyDurabilityHandler implements Listener
{
- public FlyDurabilityHandler()
+ private final boolean disableDurability;
+ private final INBTEditor nbtEditor;
+ private final DurabilityManager durabilityManager;
+
+ public FlyDurabilityHandler(boolean disableDurability, INBTEditor nbtEditor, DurabilityManager durabilityManager)
{
+ this.disableDurability = disableDurability;
+ this.nbtEditor = nbtEditor;
+ this.durabilityManager = durabilityManager;
}
- // Do not decrease elytra durability while flying. This also cancels durability decrease when
- // it should (i.e. getting hit) while flying, but I don't really care.
- @EventHandler
+ // Do not decrease elytra durability while flying.
+ @EventHandler(priority = EventPriority.LOWEST)
public void onItemDamage(PlayerItemDamageEvent e)
{
if (e.getItem().getType() != Material.ELYTRA)
@@ -24,7 +33,18 @@ public class FlyDurabilityHandler implements Listener
if (!e.getPlayer().isGliding())
return;
- if (ArmoredElytra.getInstance().getNbtEditor().getArmorTier(e.getItem()) != ArmorTier.NONE)
- e.setCancelled(true);
+ final ArmorTier armorTier = nbtEditor.getArmorTier(e.getItem());
+ if (armorTier == ArmorTier.NONE)
+ return;
+
+ // This also cancels durability decrease when it should (i.e. getting hit) while flying,
+ // but that is likely to be rare enough for it to not matter.
+ e.setCancelled(true);
+ if (disableDurability)
+ return;
+
+ final int newDurability = durabilityManager.removeDurability(e.getItem(), e.getDamage(), armorTier);
+ if (newDurability >= durabilityManager.getMaxDurability(armorTier))
+ Util.moveChestplateToInventory(e.getPlayer());
}
}
diff --git a/src/main/java/nl/pim16aap2/armoredElytra/handlers/ItemDropListener.java b/src/main/java/nl/pim16aap2/armoredElytra/handlers/ItemDropListener.java
index 617a7d2..acb0be4 100644
--- a/src/main/java/nl/pim16aap2/armoredElytra/handlers/ItemDropListener.java
+++ b/src/main/java/nl/pim16aap2/armoredElytra/handlers/ItemDropListener.java
@@ -1,6 +1,6 @@
package nl.pim16aap2.armoredElytra.handlers;
-import nl.pim16aap2.armoredElytra.ArmoredElytra;
+import nl.pim16aap2.armoredElytra.nbtEditor.INBTEditor;
import nl.pim16aap2.armoredElytra.util.ArmorTier;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
@@ -13,11 +13,11 @@ import org.bukkit.inventory.ItemStack;
public class ItemDropListener implements Listener
{
- protected final ArmoredElytra plugin;
+ private final INBTEditor nbtEditor;
- public ItemDropListener(final ArmoredElytra plugin)
+ public ItemDropListener(INBTEditor nbtEditor)
{
- this.plugin = plugin;
+ this.nbtEditor = nbtEditor;
}
/**
@@ -32,10 +32,10 @@ public class ItemDropListener implements Listener
private ItemStack getNewDrop(final ItemStack itemStack)
{
if (itemStack == null || itemStack.getType() != Material.ELYTRA ||
- plugin.getNbtEditor().getArmorTier(itemStack) != ArmorTier.NETHERITE)
+ nbtEditor.getArmorTier(itemStack) != ArmorTier.NETHERITE)
return null;
- ItemStack newDrop = new ItemStack(Material.NETHERITE_CHESTPLATE, 1);
+ final ItemStack newDrop = new ItemStack(Material.NETHERITE_CHESTPLATE, 1);
newDrop.setItemMeta(itemStack.getItemMeta());
return newDrop;
@@ -53,10 +53,10 @@ public class ItemDropListener implements Listener
private ItemStack getNewPickup(final ItemStack itemStack)
{
if (itemStack == null || itemStack.getType() != Material.NETHERITE_CHESTPLATE ||
- plugin.getNbtEditor().getArmorTier(itemStack) != ArmorTier.NETHERITE)
+ nbtEditor.getArmorTier(itemStack) != ArmorTier.NETHERITE)
return null;
- ItemStack newDrop = new ItemStack(Material.ELYTRA, 1);
+ final ItemStack newDrop = new ItemStack(Material.ELYTRA, 1);
newDrop.setItemMeta(itemStack.getItemMeta());
return newDrop;
diff --git a/src/main/java/nl/pim16aap2/armoredElytra/handlers/NetheriteUpgradeListener.java b/src/main/java/nl/pim16aap2/armoredElytra/handlers/NetheriteUpgradeListener.java
index 0c011f4..bfbd6b7 100644
--- a/src/main/java/nl/pim16aap2/armoredElytra/handlers/NetheriteUpgradeListener.java
+++ b/src/main/java/nl/pim16aap2/armoredElytra/handlers/NetheriteUpgradeListener.java
@@ -1,7 +1,10 @@
package nl.pim16aap2.armoredElytra.handlers;
import nl.pim16aap2.armoredElytra.ArmoredElytra;
+import nl.pim16aap2.armoredElytra.DurabilityManager;
+import nl.pim16aap2.armoredElytra.nbtEditor.INBTEditor;
import nl.pim16aap2.armoredElytra.util.ArmorTier;
+import nl.pim16aap2.armoredElytra.util.ConfigLoader;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -12,12 +15,13 @@ import org.bukkit.inventory.SmithingInventory;
public class NetheriteUpgradeListener extends SmithingTableListener
{
- public NetheriteUpgradeListener(final ArmoredElytra plugin)
+ public NetheriteUpgradeListener(final ArmoredElytra plugin, INBTEditor nbtEditor,
+ DurabilityManager durabilityManager, ConfigLoader config)
{
- super(plugin);
+ super(plugin, false, nbtEditor, durabilityManager, config);
}
- @EventHandler(ignoreCancelled = true)
+ @Override @EventHandler(ignoreCancelled = true)
public void onSmithingTableUsage(final PrepareSmithingEvent event)
{
super.onSmithingTableUsage(event);
diff --git a/src/main/java/nl/pim16aap2/armoredElytra/handlers/SmithingTableCraftHandler.java b/src/main/java/nl/pim16aap2/armoredElytra/handlers/SmithingTableCraftHandler.java
index 46153cb..ec470ea 100644
--- a/src/main/java/nl/pim16aap2/armoredElytra/handlers/SmithingTableCraftHandler.java
+++ b/src/main/java/nl/pim16aap2/armoredElytra/handlers/SmithingTableCraftHandler.java
@@ -1,7 +1,10 @@
package nl.pim16aap2.armoredElytra.handlers;
import nl.pim16aap2.armoredElytra.ArmoredElytra;
+import nl.pim16aap2.armoredElytra.DurabilityManager;
+import nl.pim16aap2.armoredElytra.nbtEditor.INBTEditor;
import nl.pim16aap2.armoredElytra.util.ArmorTier;
+import nl.pim16aap2.armoredElytra.util.ConfigLoader;
import nl.pim16aap2.armoredElytra.util.Util;
import org.bukkit.Bukkit;
import org.bukkit.Material;
@@ -14,13 +17,16 @@ import org.bukkit.inventory.SmithingInventory;
public class SmithingTableCraftHandler extends SmithingTableListener
{
- public SmithingTableCraftHandler(final ArmoredElytra plugin)
+ public SmithingTableCraftHandler(final ArmoredElytra plugin, INBTEditor nbtEditor,
+ DurabilityManager durabilityManager, ConfigLoader config)
{
- super(plugin, true);
+ super(plugin, true, nbtEditor, durabilityManager, config);
// Register the anvil handler with creation disabled so AEs can still be repaired and stuff.
- Bukkit.getPluginManager().registerEvents(new AnvilHandler(plugin, false), plugin);
+ Bukkit.getPluginManager()
+ .registerEvents(new AnvilHandler(plugin, false, nbtEditor, durabilityManager, config), plugin);
}
+ @Override
@EventHandler(ignoreCancelled = true)
public void onSmithingTableUsage(final PrepareSmithingEvent event)
{
@@ -42,7 +48,7 @@ public class SmithingTableCraftHandler extends SmithingTableListener
{
if (!isAESmithingTableEvent(e))
return;
- SmithingInventory smithingInventory = (SmithingInventory) e.getInventory();
+ final SmithingInventory smithingInventory = (SmithingInventory) e.getInventory();
final ItemStack result = smithingInventory.getItem(2);
// This cast may look unchecked, but it was checked by isSmithingTableEvent already.
diff --git a/src/main/java/nl/pim16aap2/armoredElytra/handlers/SmithingTableListener.java b/src/main/java/nl/pim16aap2/armoredElytra/handlers/SmithingTableListener.java
index c205b58..dabd73b 100644
--- a/src/main/java/nl/pim16aap2/armoredElytra/handlers/SmithingTableListener.java
+++ b/src/main/java/nl/pim16aap2/armoredElytra/handlers/SmithingTableListener.java
@@ -1,7 +1,10 @@
package nl.pim16aap2.armoredElytra.handlers;
import nl.pim16aap2.armoredElytra.ArmoredElytra;
+import nl.pim16aap2.armoredElytra.DurabilityManager;
+import nl.pim16aap2.armoredElytra.nbtEditor.INBTEditor;
import nl.pim16aap2.armoredElytra.util.ArmorTier;
+import nl.pim16aap2.armoredElytra.util.ConfigLoader;
import nl.pim16aap2.armoredElytra.util.EnchantmentContainer;
import org.bukkit.Color;
import org.bukkit.Material;
@@ -17,15 +20,10 @@ import java.util.logging.Level;
abstract class SmithingTableListener extends ArmoredElytraHandler implements Listener
{
- protected SmithingTableListener(ArmoredElytra plugin, boolean creationEnabled)
+ protected SmithingTableListener(ArmoredElytra plugin, boolean creationEnabled,
+ INBTEditor nbtEditor, DurabilityManager durabilityManager, ConfigLoader config)
{
- super(plugin, creationEnabled);
-
- }
-
- protected SmithingTableListener(ArmoredElytra plugin)
- {
- this(plugin, false);
+ super(plugin, creationEnabled, nbtEditor, durabilityManager, config);
}
public void onSmithingTableUsage(final PrepareSmithingEvent event)
@@ -42,17 +40,17 @@ abstract class SmithingTableListener extends ArmoredElytraHandler implements Lis
final Player player = (Player) event.getView().getPlayer();
- final ItemStack result;
if (plugin.playerHasCraftPerm(player, newTier))
{
-
- EnchantmentContainer enchantments = EnchantmentContainer.getEnchantments(itemStackA, plugin);
+ final EnchantmentContainer enchantments = EnchantmentContainer.getEnchantments(itemStackA, plugin);
enchantments.merge(EnchantmentContainer.getEnchantments(itemStackB, plugin));
final Color color = getItemColor(itemStackA, itemStackB);
- result = ArmoredElytra.getInstance().getNbtEditor()
- .addArmorNBTTags(new ItemStack(Material.ELYTRA, 1), newTier,
- plugin.getConfigLoader().unbreakable(), color);
+ 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);
}
@@ -82,7 +80,7 @@ abstract class SmithingTableListener extends ArmoredElytraHandler implements Lis
return false;
// Check if the event was a player who interacted with a smithing table.
- Player player = (Player) event.getWhoClicked();
+ final Player player = (Player) event.getWhoClicked();
if (event.getView().getType() != InventoryType.SMITHING)
return false;
@@ -110,9 +108,8 @@ abstract class SmithingTableListener extends ArmoredElytraHandler implements Lis
final ItemStack result = smithingInventory.getItem(2);
if (result == null || result.getType() != Material.ELYTRA ||
- ArmoredElytra.getInstance().getNbtEditor().getArmorTier(result) == ArmorTier.NONE)
+ nbtEditor.getArmorTier(result) == ArmorTier.NONE)
return false;
-
return true;
}
}
diff --git a/src/main/java/nl/pim16aap2/armoredElytra/handlers/Uninstaller.java b/src/main/java/nl/pim16aap2/armoredElytra/handlers/Uninstaller.java
index b745f58..fadf2d9 100644
--- a/src/main/java/nl/pim16aap2/armoredElytra/handlers/Uninstaller.java
+++ b/src/main/java/nl/pim16aap2/armoredElytra/handlers/Uninstaller.java
@@ -1,6 +1,7 @@
package nl.pim16aap2.armoredElytra.handlers;
import nl.pim16aap2.armoredElytra.ArmoredElytra;
+import nl.pim16aap2.armoredElytra.nbtEditor.INBTEditor;
import nl.pim16aap2.armoredElytra.util.ArmorTier;
import org.bukkit.ChatColor;
import org.bukkit.Material;
@@ -17,10 +18,12 @@ import org.bukkit.scheduler.BukkitRunnable;
public class Uninstaller implements Listener
{
private final ArmoredElytra plugin;
+ private final INBTEditor nbtEditor;
- public Uninstaller(ArmoredElytra plugin)
+ public Uninstaller(ArmoredElytra plugin, INBTEditor nbtEditor)
{
this.plugin = plugin;
+ this.nbtEditor = nbtEditor;
}
public int removeArmoredElytras(Inventory inv)
@@ -28,7 +31,7 @@ public class Uninstaller implements Listener
int count = 0;
for (ItemStack is : inv)
if (is != null && is.getType() == Material.ELYTRA &&
- ArmoredElytra.getInstance().getNbtEditor().getArmorTier(is) != ArmorTier.NONE)
+ nbtEditor.getArmorTier(is) != ArmorTier.NONE)
{
inv.remove(is);
++count;
diff --git a/src/main/java/nl/pim16aap2/armoredElytra/nbtEditor/INBTEditor.java b/src/main/java/nl/pim16aap2/armoredElytra/nbtEditor/INBTEditor.java
index 6c1449b..0d436df 100644
--- a/src/main/java/nl/pim16aap2/armoredElytra/nbtEditor/INBTEditor.java
+++ b/src/main/java/nl/pim16aap2/armoredElytra/nbtEditor/INBTEditor.java
@@ -130,12 +130,4 @@ public interface INBTEditor
* @return The real durability of the itemstack if the itemstack has the AE durability attribute, or -1 otherwise.
*/
int getRealDurability(ItemStack itemStack, @Nullable ArmorTier armorTier);
-
- /**
- * See {@link #getRealDurability(ItemStack, ArmorTier)}.
- */
- default int getRealDurability(ItemStack itemStack)
- {
- return getRealDurability(itemStack, null);
- }
}
diff --git a/src/main/java/nl/pim16aap2/armoredElytra/util/ConfigLoader.java b/src/main/java/nl/pim16aap2/armoredElytra/util/ConfigLoader.java
index 6c0ab2e..025e837 100644
--- a/src/main/java/nl/pim16aap2/armoredElytra/util/ConfigLoader.java
+++ b/src/main/java/nl/pim16aap2/armoredElytra/util/ConfigLoader.java
@@ -35,6 +35,7 @@ public class ConfigLoader
private boolean uninstallMode;
private boolean checkForUpdates;
private boolean noFlightDurability;
+ private boolean useTierDurability;
private boolean dropNetheriteAsChestplate;
private LinkedHashSet