diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/enchanting/AbstractEnchantmentMachine.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/enchanting/AbstractEnchantmentMachine.java new file mode 100644 index 000000000..438016d21 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/enchanting/AbstractEnchantmentMachine.java @@ -0,0 +1,58 @@ +package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.enchanting; + +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; +import io.github.thebusybiscuit.cscorelib2.item.CustomItem; +import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; +import io.github.thebusybiscuit.slimefun4.api.items.settings.IntRangeSetting; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +import me.mrCookieSlime.Slimefun.Lists.RecipeType; +import me.mrCookieSlime.Slimefun.Objects.Category; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; +import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; +import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; + +/** + * This is a super class of the {@link AutoEnchanter} and {@link AutoDisenchanter} which is + * used to streamline some methods and combine common attributes to reduce redundancy. + * + * @author TheBusyBiscuit + * + * @see AutoEnchanter + * @see AutoDisenchanter + * + */ +abstract class AbstractEnchantmentMachine extends AContainer { + + private final ItemSetting useLevelLimit = new ItemSetting<>(this, "use-enchant-level-limit", false); + private final IntRangeSetting levelLimit = new IntRangeSetting(this, "enchant-level-limit", 0, 10, Short.MAX_VALUE); + + @ParametersAreNonnullByDefault + protected AbstractEnchantmentMachine(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { + super(category, item, recipeType, recipe); + + addItemSetting(useLevelLimit); + addItemSetting(levelLimit); + } + + protected boolean isEnchantmentLevelAllowed(int enchantmentLevel) { + return !useLevelLimit.getValue() || levelLimit.getValue() >= enchantmentLevel; + } + + protected void showEnchantmentLevelWarning(@Nonnull BlockMenu menu) { + if (!useLevelLimit.getValue()) { + throw new IllegalStateException("Enchantment level limit not enabled, cannot display a warning."); + } + + String notice = ChatColors.color(SlimefunPlugin.getLocalization().getMessage("messages.above-limit-level")); + notice = notice.replace("%level%", String.valueOf(levelLimit.getValue())); + ItemStack progressBar = new CustomItem(Material.BARRIER, " ", notice); + menu.replaceExistingItem(22, progressBar); + } + +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/enchanting/AutoDisenchanter.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/enchanting/AutoDisenchanter.java index 2cf6650f7..8d69cbc30 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/enchanting/AutoDisenchanter.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/enchanting/AutoDisenchanter.java @@ -14,17 +14,11 @@ import org.bukkit.inventory.meta.EnchantmentStorageMeta; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.Repairable; -import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; import io.github.thebusybiscuit.cscorelib2.inventory.InvUtils; -import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.slimefun4.api.events.AutoDisenchantEvent; -import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; -import io.github.thebusybiscuit.slimefun4.api.items.settings.IntRangeSetting; -import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; @@ -46,17 +40,11 @@ import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; * @see AutoEnchanter * */ -public class AutoDisenchanter extends AContainer { - - private final ItemSetting useEnchantLevelLimit = new ItemSetting<>(this, "use-enchant-level-limit", false); - private final IntRangeSetting enchantLevelLimit = new IntRangeSetting(this, "enchant-level-limit", 0, 10, Short.MAX_VALUE); +public class AutoDisenchanter extends AbstractEnchantmentMachine { @ParametersAreNonnullByDefault public AutoDisenchanter(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { super(category, item, recipeType, recipe); - - addItemSetting(useEnchantLevelLimit); - addItemSetting(enchantLevelLimit); } @Override @@ -66,8 +54,6 @@ public class AutoDisenchanter extends AContainer { @Override protected MachineRecipe findNextRecipe(BlockMenu menu) { - Map enchantments = new HashMap<>(); - for (int slot : getInputSlots()) { ItemStack item = menu.getItemInSlot(slot); @@ -75,6 +61,7 @@ public class AutoDisenchanter extends AContainer { return null; } + // Call an event so other Plugins can modify it. AutoDisenchantEvent event = new AutoDisenchantEvent(item); Bukkit.getPluginManager().callEvent(event); @@ -82,50 +69,58 @@ public class AutoDisenchanter extends AContainer { return null; } - ItemStack target = menu.getItemInSlot(slot == getInputSlots()[0] ? getInputSlots()[1] : getInputSlots()[0]); + ItemStack secondItem = menu.getItemInSlot(slot == getInputSlots()[0] ? getInputSlots()[1] : getInputSlots()[0]); - // Disenchanting - if (target != null && target.getType() == Material.BOOK) { - int amount = 0; - - for (Map.Entry entry : item.getEnchantments().entrySet()) { - if (!useEnchantLevelLimit.getValue() || enchantLevelLimit.getValue() >= entry.getValue()) { - enchantments.put(entry.getKey(), entry.getValue()); - amount++; - } else if (!menu.toInventory().getViewers().isEmpty()) { - String notice = ChatColors.color(SlimefunPlugin.getLocalization().getMessage("messages.above-limit-level")); - notice = notice.replace("%level%", String.valueOf(enchantLevelLimit.getValue())); - ItemStack progressBar = new CustomItem(Material.BARRIER, " ", notice); - menu.replaceExistingItem(22, progressBar); - return null; - } - } - - if (amount > 0) { - ItemStack disenchantedItem = item.clone(); - disenchantedItem.setAmount(1); - - ItemStack book = new ItemStack(Material.ENCHANTED_BOOK); - transferEnchantments(disenchantedItem, book, enchantments); - - MachineRecipe recipe = new MachineRecipe(90 * amount / this.getSpeed(), new ItemStack[] { target, item }, new ItemStack[] { disenchantedItem, book }); - - if (!InvUtils.fitAll(menu.toInventory(), recipe.getOutput(), getOutputSlots())) { - return null; - } - - for (int inputSlot : getInputSlots()) { - menu.consumeItem(inputSlot); - } - - return recipe; - } + if (secondItem != null && secondItem.getType() == Material.BOOK) { + return disenchant(menu, item, secondItem); } } return null; } + @Nullable + @ParametersAreNonnullByDefault + private MachineRecipe disenchant(BlockMenu menu, ItemStack item, ItemStack book) { + Map enchantments = new HashMap<>(); + int amount = 0; + + // Find enchantments + for (Map.Entry entry : item.getEnchantments().entrySet()) { + if (isEnchantmentLevelAllowed(entry.getValue())) { + enchantments.put(entry.getKey(), entry.getValue()); + amount++; + } else if (!menu.toInventory().getViewers().isEmpty()) { + showEnchantmentLevelWarning(menu); + return null; + } + } + + // Check if we found any valid enchantments + if (amount > 0) { + ItemStack disenchantedItem = item.clone(); + disenchantedItem.setAmount(1); + + ItemStack enchantedBook = new ItemStack(Material.ENCHANTED_BOOK); + transferEnchantments(disenchantedItem, enchantedBook, enchantments); + + MachineRecipe recipe = new MachineRecipe(90 * amount / this.getSpeed(), new ItemStack[] { book, item }, new ItemStack[] { disenchantedItem, enchantedBook }); + + if (!InvUtils.fitAll(menu.toInventory(), recipe.getOutput(), getOutputSlots())) { + return null; + } + + for (int inputSlot : getInputSlots()) { + menu.consumeItem(inputSlot); + } + + return recipe; + } else { + return null; + } + } + + @ParametersAreNonnullByDefault private void transferEnchantments(ItemStack item, ItemStack book, Map enchantments) { ItemMeta itemMeta = item.getItemMeta(); ItemMeta bookMeta = book.getItemMeta(); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/enchanting/AutoEnchanter.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/enchanting/AutoEnchanter.java index 2ef26411e..bb82488bf 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/enchanting/AutoEnchanter.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/enchanting/AutoEnchanter.java @@ -12,17 +12,11 @@ import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.EnchantmentStorageMeta; -import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; import io.github.thebusybiscuit.cscorelib2.inventory.InvUtils; -import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.slimefun4.api.events.AutoEnchantEvent; -import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; -import io.github.thebusybiscuit.slimefun4.api.items.settings.IntRangeSetting; -import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; @@ -40,17 +34,11 @@ import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; * @see AutoDisenchanter * */ -public class AutoEnchanter extends AContainer { - - private final ItemSetting useEnchantLevelLimit = new ItemSetting<>(this, "use-enchant-level-limit", false); - private final IntRangeSetting enchantLevelLimit = new IntRangeSetting(this, "enchant-level-limit", 0, 10, Short.MAX_VALUE); +public class AutoEnchanter extends AbstractEnchantmentMachine { @ParametersAreNonnullByDefault public AutoEnchanter(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { super(category, item, recipeType, recipe); - - addItemSetting(useEnchantLevelLimit); - addItemSetting(enchantLevelLimit); } @Override @@ -61,70 +49,76 @@ public class AutoEnchanter extends AContainer { @Override protected MachineRecipe findNextRecipe(BlockMenu menu) { for (int slot : getInputSlots()) { - ItemStack target = menu.getItemInSlot(slot == getInputSlots()[0] ? getInputSlots()[1] : getInputSlots()[0]); + ItemStack item = menu.getItemInSlot(slot == getInputSlots()[0] ? getInputSlots()[1] : getInputSlots()[0]); // Check if the item is enchantable - if (!isEnchantable(target)) { + if (!isEnchantable(item)) { return null; } - AutoEnchantEvent event = new AutoEnchantEvent(target); + // Call an event so other Plugins can modify it. + AutoEnchantEvent event = new AutoEnchantEvent(item); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { return null; } - ItemStack item = menu.getItemInSlot(slot); + ItemStack secondItem = menu.getItemInSlot(slot); - if (item != null && item.getType() == Material.ENCHANTED_BOOK && target != null) { - Map enchantments = new HashMap<>(); - int amount = 0; - EnchantmentStorageMeta meta = (EnchantmentStorageMeta) item.getItemMeta(); - - for (Map.Entry e : meta.getStoredEnchants().entrySet()) { - if (e.getKey().canEnchantItem(target)) { - if (!useEnchantLevelLimit.getValue() || enchantLevelLimit.getValue() >= e.getValue()) { - amount++; - enchantments.put(e.getKey(), e.getValue()); - } else if (!menu.toInventory().getViewers().isEmpty()) { - String notice = ChatColors.color(SlimefunPlugin.getLocalization().getMessage("messages.above-limit-level")); - notice = notice.replace("%level%", String.valueOf(enchantLevelLimit.getValue())); - ItemStack progressBar = new CustomItem(Material.BARRIER, " ", notice); - menu.replaceExistingItem(22, progressBar); - return null; - } - } - } - - if (amount > 0) { - ItemStack enchantedItem = target.clone(); - enchantedItem.setAmount(1); - - for (Map.Entry entry : enchantments.entrySet()) { - enchantedItem.addUnsafeEnchantment(entry.getKey(), entry.getValue()); - } - - MachineRecipe recipe = new MachineRecipe(75 * amount / this.getSpeed(), new ItemStack[] { target, item }, new ItemStack[] { enchantedItem, new ItemStack(Material.BOOK) }); - - if (!InvUtils.fitAll(menu.toInventory(), recipe.getOutput(), getOutputSlots())) { - return null; - } - - for (int inputSlot : getInputSlots()) { - menu.consumeItem(inputSlot); - } - - return recipe; - } - - return null; + if (secondItem != null && secondItem.getType() == Material.ENCHANTED_BOOK) { + return enchant(menu, item, secondItem); } } return null; } + @Nullable + @ParametersAreNonnullByDefault + protected MachineRecipe enchant(BlockMenu menu, ItemStack target, ItemStack enchantedBook) { + EnchantmentStorageMeta meta = (EnchantmentStorageMeta) enchantedBook.getItemMeta(); + Map enchantments = new HashMap<>(); + int amount = 0; + + // Find applicable enchantments + for (Map.Entry entry : meta.getStoredEnchants().entrySet()) { + if (entry.getKey().canEnchantItem(target)) { + if (isEnchantmentLevelAllowed(entry.getValue())) { + amount++; + enchantments.put(entry.getKey(), entry.getValue()); + } else if (!menu.toInventory().getViewers().isEmpty()) { + showEnchantmentLevelWarning(menu); + return null; + } + } + } + + // Check if we found any valid enchantments + if (amount > 0) { + ItemStack enchantedItem = target.clone(); + enchantedItem.setAmount(1); + + for (Map.Entry entry : enchantments.entrySet()) { + enchantedItem.addUnsafeEnchantment(entry.getKey(), entry.getValue()); + } + + MachineRecipe recipe = new MachineRecipe(75 * amount / this.getSpeed(), new ItemStack[] { target, enchantedBook }, new ItemStack[] { enchantedItem, new ItemStack(Material.BOOK) }); + + if (!InvUtils.fitAll(menu.toInventory(), recipe.getOutput(), getOutputSlots())) { + return null; + } + + for (int inputSlot : getInputSlots()) { + menu.consumeItem(inputSlot); + } + + return recipe; + } else { + return null; + } + } + private boolean isEnchantable(@Nullable ItemStack item) { // stops endless checks of getByItem for enchanted book stacks. if (item != null && item.getType() != Material.ENCHANTED_BOOK) {