diff --git a/NMS/src/main/templates/AbstractNMSAdapter.java.template b/NMS/src/main/templates/AbstractNMSAdapter.java.template index 9f868246..4d5549b9 100644 --- a/NMS/src/main/templates/AbstractNMSAdapter.java.template +++ b/NMS/src/main/templates/AbstractNMSAdapter.java.template @@ -17,15 +17,12 @@ import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.inventory.AnvilMenu; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.block.BlockFace; import ${CRAFTBUKKIT_PACKAGE}.CraftWorld; -import ${CRAFTBUKKIT_PACKAGE}.block.data.CraftBlockData; import ${CRAFTBUKKIT_PACKAGE}.entity.CraftItem; import ${CRAFTBUKKIT_PACKAGE}.entity.CraftLivingEntity; import ${CRAFTBUKKIT_PACKAGE}.inventory.CraftInventoryView; @@ -43,9 +40,11 @@ import org.bukkit.inventory.RecipeChoice; import org.bukkit.inventory.ShapedRecipe; import org.bukkit.inventory.ShapelessRecipe; import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.Tag; import java.util.ArrayList; import java.util.Collection; +import java.util.EnumMap; import java.util.List; public abstract class AbstractNMSAdapter implements NMSAdapter { @@ -53,6 +52,8 @@ public abstract class AbstractNMSAdapter implements NMSAdapter { private static final ReflectField ITEM_STACK_HANDLE = new ReflectField<>( CraftItemStack.class, ItemStack.class, "handle"); + private static final EnumMap DESTROY_SPEED_CATEGORIES = new EnumMap<>(Material.class); + @Override public void loadLegacy() { // Load legacy by accessing the CraftLegacy class. @@ -139,16 +140,22 @@ public abstract class AbstractNMSAdapter implements NMSAdapter { protected abstract void sendPacket(ServerChunkCache serverChunkCache, Entity entity, Packet packet); @Override - public DestroySpeedCategory getDestroySpeedCategory(Material material) { - BlockState blockState = ((CraftBlockData) material.createBlockData()).getState(); + public synchronized DestroySpeedCategory getDestroySpeedCategory(Material material) { + return DESTROY_SPEED_CATEGORIES.computeIfAbsent(material, mat -> { + if (Tag.MINEABLE_AXE.isTagged(mat)) { + return DestroySpeedCategory.AXE; + } - if (Items.DIAMOND_AXE.getDestroySpeed(new ItemStack(Items.DIAMOND_AXE), blockState) == 8f) - return DestroySpeedCategory.AXE; + if (Tag.MINEABLE_HOE.isTagged(mat)) { + return DestroySpeedCategory.HOE; + } - if (Items.DIAMOND_SHOVEL.getDestroySpeed(new ItemStack(Items.DIAMOND_SHOVEL), blockState) == 8f) - return DestroySpeedCategory.SHOVEL; + if (Tag.MINEABLE_SHOVEL.isTagged(mat)) { + return DestroySpeedCategory.SHOVEL; + } - return DestroySpeedCategory.PICKAXE; + return DestroySpeedCategory.PICKAXE; + }); } @Override diff --git a/NMS/v1_12_R1/src/main/java/com/bgsoftware/wildtools/nms/v1_12_R1/NMSAdapterImpl.java b/NMS/v1_12_R1/src/main/java/com/bgsoftware/wildtools/nms/v1_12_R1/NMSAdapterImpl.java index 40a73805..80994670 100644 --- a/NMS/v1_12_R1/src/main/java/com/bgsoftware/wildtools/nms/v1_12_R1/NMSAdapterImpl.java +++ b/NMS/v1_12_R1/src/main/java/com/bgsoftware/wildtools/nms/v1_12_R1/NMSAdapterImpl.java @@ -40,12 +40,18 @@ import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; +import java.util.EnumMap; public class NMSAdapterImpl implements NMSAdapter { private static final ReflectField ITEM_STACK_HANDLE = new ReflectField<>(CraftItemStack.class, ItemStack.class, "handle"); + private static final EnumMap DESTROY_SPEED_CATEGORIES = new EnumMap<>(Material.class); + private static final Enchantment GLOW_ENCHANT = initializeGlowEnchantment(); + private static final ItemStack DIAMOND_AXE_ITEM_STACK = new ItemStack(Items.DIAMOND_AXE); + private static final ItemStack DIAMOND_HOE_ITEM_STACK = new ItemStack(Items.DIAMOND_HOE); + private static final ItemStack DIAMOND_SHOVEL_ITEM_STACK = new ItemStack(Items.DIAMOND_SHOVEL); @Override public ToolItemStack createToolItemStack(org.bukkit.inventory.ItemStack bukkitItem) { @@ -122,16 +128,24 @@ public void playPickupAnimation(LivingEntity livingEntity, org.bukkit.entity.Ite } @Override - public DestroySpeedCategory getDestroySpeedCategory(Material material) { - IBlockData blockData = CraftMagicNumbers.getBlock(material).getBlockData(); + public synchronized DestroySpeedCategory getDestroySpeedCategory(Material material) { + return DESTROY_SPEED_CATEGORIES.computeIfAbsent(material, mat -> { + IBlockData blockData = CraftMagicNumbers.getBlock(mat).getBlockData(); - if (Items.DIAMOND_AXE.getDestroySpeed(new ItemStack(Items.DIAMOND_AXE), blockData) == 8f) - return DestroySpeedCategory.AXE; + if (Items.DIAMOND_AXE.getDestroySpeed(DIAMOND_AXE_ITEM_STACK, blockData) == 8f) { + return DestroySpeedCategory.AXE; + } - if (Items.DIAMOND_SHOVEL.getDestroySpeed(new ItemStack(Items.DIAMOND_SHOVEL), blockData) == 8f) - return DestroySpeedCategory.SHOVEL; + if (Items.DIAMOND_HOE.getDestroySpeed(DIAMOND_HOE_ITEM_STACK, blockData) == 8f) { + return DestroySpeedCategory.HOE; + } + + if (Items.DIAMOND_SHOVEL.getDestroySpeed(DIAMOND_SHOVEL_ITEM_STACK, blockData) == 8f) { + return DestroySpeedCategory.SHOVEL; + } - return DestroySpeedCategory.PICKAXE; + return DestroySpeedCategory.PICKAXE; + }); } @Override diff --git a/NMS/v1_16_R3/src/main/java/com/bgsoftware/wildtools/nms/v1_16_R3/NMSAdapterImpl.java b/NMS/v1_16_R3/src/main/java/com/bgsoftware/wildtools/nms/v1_16_R3/NMSAdapterImpl.java index f8764322..5a4153d2 100644 --- a/NMS/v1_16_R3/src/main/java/com/bgsoftware/wildtools/nms/v1_16_R3/NMSAdapterImpl.java +++ b/NMS/v1_16_R3/src/main/java/com/bgsoftware/wildtools/nms/v1_16_R3/NMSAdapterImpl.java @@ -47,13 +47,19 @@ import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; +import java.util.EnumMap; import java.util.List; public class NMSAdapterImpl implements NMSAdapter { private static final ReflectField ITEM_STACK_HANDLE = new ReflectField<>(CraftItemStack.class, ItemStack.class, "handle"); + private static final EnumMap DESTROY_SPEED_CATEGORIES = new EnumMap<>(Material.class); + private static final Enchantment GLOW_ENCHANT = initializeGlowEnchantment(); + private static final ItemStack DIAMOND_AXE_ITEM_STACK = new ItemStack(Items.DIAMOND_AXE); + private static final ItemStack DIAMOND_HOE_ITEM_STACK = new ItemStack(Items.DIAMOND_HOE); + private static final ItemStack DIAMOND_SHOVEL_ITEM_STACK = new ItemStack(Items.DIAMOND_SHOVEL); @Override public ToolItemStack createToolItemStack(org.bukkit.inventory.ItemStack bukkitItem) { @@ -130,16 +136,24 @@ public void playPickupAnimation(LivingEntity livingEntity, org.bukkit.entity.Ite } @Override - public DestroySpeedCategory getDestroySpeedCategory(Material material) { - IBlockData blockData = CraftMagicNumbers.getBlock(material).getBlockData(); + public synchronized DestroySpeedCategory getDestroySpeedCategory(Material material) { + return DESTROY_SPEED_CATEGORIES.computeIfAbsent(material, mat -> { + IBlockData blockData = CraftMagicNumbers.getBlock(mat).getBlockData(); - if (Items.DIAMOND_AXE.getDestroySpeed(new ItemStack(Items.DIAMOND_AXE), blockData) == 8f) - return DestroySpeedCategory.AXE; + if (Items.DIAMOND_AXE.getDestroySpeed(DIAMOND_AXE_ITEM_STACK, blockData) == 8f) { + return DestroySpeedCategory.AXE; + } - if (Items.DIAMOND_SHOVEL.getDestroySpeed(new ItemStack(Items.DIAMOND_SHOVEL), blockData) == 8f) - return DestroySpeedCategory.SHOVEL; + if (Items.DIAMOND_HOE.getDestroySpeed(DIAMOND_HOE_ITEM_STACK, blockData) == 8f) { + return DestroySpeedCategory.HOE; + } + + if (Items.DIAMOND_SHOVEL.getDestroySpeed(DIAMOND_SHOVEL_ITEM_STACK, blockData) == 8f) { + return DestroySpeedCategory.SHOVEL; + } - return DestroySpeedCategory.PICKAXE; + return DestroySpeedCategory.PICKAXE; + }); } @Override diff --git a/NMS/v1_7_R4/src/main/java/com/bgsoftware/wildtools/nms/v1_7_R4/NMSAdapterImpl.java b/NMS/v1_7_R4/src/main/java/com/bgsoftware/wildtools/nms/v1_7_R4/NMSAdapterImpl.java index ec90b030..72022c48 100644 --- a/NMS/v1_7_R4/src/main/java/com/bgsoftware/wildtools/nms/v1_7_R4/NMSAdapterImpl.java +++ b/NMS/v1_7_R4/src/main/java/com/bgsoftware/wildtools/nms/v1_7_R4/NMSAdapterImpl.java @@ -35,13 +35,19 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.EnumMap; import java.util.List; public class NMSAdapterImpl implements NMSAdapter { private static final ReflectField ITEM_STACK_HANDLE = new ReflectField<>(CraftItemStack.class, ItemStack.class, "handle"); + private static final EnumMap DESTROY_SPEED_CATEGORIES = new EnumMap<>(Material.class); + private static final Enchantment GLOW_ENCHANT = initializeGlowEnchantment(); + private static final ItemStack DIAMOND_AXE_ITEM_STACK = new ItemStack(Items.DIAMOND_AXE); + private static final ItemStack DIAMOND_HOE_ITEM_STACK = new ItemStack(Items.DIAMOND_HOE); + private static final ItemStack DIAMOND_SPADE_ITEM_STACK = new ItemStack(Items.DIAMOND_SPADE); @Override public org.bukkit.inventory.ItemStack getItemInHand(Player player) { @@ -117,16 +123,24 @@ public void playPickupAnimation(LivingEntity livingEntity, org.bukkit.entity.Ite } @Override - public DestroySpeedCategory getDestroySpeedCategory(Material material) { - Block block = CraftMagicNumbers.getBlock(material); + public synchronized DestroySpeedCategory getDestroySpeedCategory(Material material) { + return DESTROY_SPEED_CATEGORIES.computeIfAbsent(material, mat -> { + Block block = CraftMagicNumbers.getBlock(mat); - if (Items.DIAMOND_AXE.getDestroySpeed(new ItemStack(Items.DIAMOND_AXE), block) == 8f) - return DestroySpeedCategory.AXE; + if (Items.DIAMOND_AXE.getDestroySpeed(DIAMOND_AXE_ITEM_STACK, block) == 8f) { + return DestroySpeedCategory.AXE; + } - if (Items.DIAMOND_SPADE.getDestroySpeed(new ItemStack(Items.DIAMOND_SPADE), block) == 8f) - return DestroySpeedCategory.SHOVEL; + if (Items.DIAMOND_HOE.getDestroySpeed(DIAMOND_HOE_ITEM_STACK, block) == 8f) { + return DestroySpeedCategory.HOE; + } + + if (Items.DIAMOND_SPADE.getDestroySpeed(DIAMOND_SPADE_ITEM_STACK, block) == 8f) { + return DestroySpeedCategory.SHOVEL; + } - return DestroySpeedCategory.PICKAXE; + return DestroySpeedCategory.PICKAXE; + }); } private static Enchantment initializeGlowEnchantment() { diff --git a/NMS/v1_8_R3/src/main/java/com/bgsoftware/wildtools/nms/v1_8_R3/NMSAdapterImpl.java b/NMS/v1_8_R3/src/main/java/com/bgsoftware/wildtools/nms/v1_8_R3/NMSAdapterImpl.java index 6261ce1d..eaac94f3 100644 --- a/NMS/v1_8_R3/src/main/java/com/bgsoftware/wildtools/nms/v1_8_R3/NMSAdapterImpl.java +++ b/NMS/v1_8_R3/src/main/java/com/bgsoftware/wildtools/nms/v1_8_R3/NMSAdapterImpl.java @@ -33,12 +33,18 @@ import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; +import java.util.EnumMap; public class NMSAdapterImpl implements NMSAdapter { private static final ReflectField ITEM_STACK_HANDLE = new ReflectField<>(CraftItemStack.class, ItemStack.class, "handle"); + private static final EnumMap DESTROY_SPEED_CATEGORIES = new EnumMap<>(Material.class); + private static final Enchantment GLOW_ENCHANT = initializeGlowEnchantment(); + private static final ItemStack DIAMOND_AXE_ITEM_STACK = new ItemStack(Items.DIAMOND_AXE); + private static final ItemStack DIAMOND_HOE_ITEM_STACK = new ItemStack(Items.DIAMOND_HOE); + private static final ItemStack DIAMOND_SHOVEL_ITEM_STACK = new ItemStack(Items.DIAMOND_SHOVEL); @Override public ToolItemStack createToolItemStack(org.bukkit.inventory.ItemStack bukkitItem) { @@ -105,16 +111,24 @@ public void playPickupAnimation(LivingEntity livingEntity, org.bukkit.entity.Ite } @Override - public DestroySpeedCategory getDestroySpeedCategory(Material material) { - Block block = CraftMagicNumbers.getBlock(material); + public synchronized DestroySpeedCategory getDestroySpeedCategory(Material material) { + return DESTROY_SPEED_CATEGORIES.computeIfAbsent(material, mat -> { + Block block = CraftMagicNumbers.getBlock(mat); - if (Items.DIAMOND_AXE.getDestroySpeed(new ItemStack(Items.DIAMOND_AXE), block) == 8f) - return DestroySpeedCategory.AXE; + if (Items.DIAMOND_AXE.getDestroySpeed(DIAMOND_AXE_ITEM_STACK, block) == 8f) { + return DestroySpeedCategory.AXE; + } - if (Items.DIAMOND_SHOVEL.getDestroySpeed(new ItemStack(Items.DIAMOND_SHOVEL), block) == 8f) - return DestroySpeedCategory.SHOVEL; + if (Items.DIAMOND_HOE.getDestroySpeed(DIAMOND_HOE_ITEM_STACK, block) == 8f) { + return DestroySpeedCategory.HOE; + } + + if (Items.DIAMOND_SHOVEL.getDestroySpeed(DIAMOND_SHOVEL_ITEM_STACK, block) == 8f) { + return DestroySpeedCategory.SHOVEL; + } - return DestroySpeedCategory.PICKAXE; + return DestroySpeedCategory.PICKAXE; + }); } private static Enchantment initializeGlowEnchantment() { diff --git a/src/main/java/com/bgsoftware/wildtools/WildToolsPlugin.java b/src/main/java/com/bgsoftware/wildtools/WildToolsPlugin.java index 45e107b3..2842a11e 100644 --- a/src/main/java/com/bgsoftware/wildtools/WildToolsPlugin.java +++ b/src/main/java/com/bgsoftware/wildtools/WildToolsPlugin.java @@ -22,6 +22,7 @@ import com.bgsoftware.wildtools.listeners.PlayerListener; import com.bgsoftware.wildtools.nms.NMSAdapter; import com.bgsoftware.wildtools.nms.NMSWorld; +import com.bgsoftware.wildtools.utils.items.OmniToolHelper; import org.bstats.bukkit.Metrics; import org.bukkit.entity.Player; import org.bukkit.event.inventory.InventoryType; @@ -70,6 +71,8 @@ public void onEnable() { log("******** ENABLE START ********"); + OmniToolHelper.init(); + try { Class.forName("org.bukkit.event.inventory.PrepareAnvilEvent"); getServer().getPluginManager().registerEvents(new AnvilListener(this), this); diff --git a/src/main/java/com/bgsoftware/wildtools/listeners/BlocksListener.java b/src/main/java/com/bgsoftware/wildtools/listeners/BlocksListener.java index 041d60a3..39ccab54 100644 --- a/src/main/java/com/bgsoftware/wildtools/listeners/BlocksListener.java +++ b/src/main/java/com/bgsoftware/wildtools/listeners/BlocksListener.java @@ -4,9 +4,11 @@ import com.bgsoftware.wildtools.WildToolsPlugin; import com.bgsoftware.wildtools.api.objects.tools.Tool; import com.bgsoftware.wildtools.tools.ToolBreaksTracker; -import com.bgsoftware.wildtools.utils.ServerVersion; +import com.bgsoftware.wildtools.utils.items.DestroySpeedCategory; +import com.bgsoftware.wildtools.utils.items.OmniToolHelper; import com.bgsoftware.wildtools.utils.items.ToolItemStack; import org.bukkit.Material; +import org.bukkit.World; import org.bukkit.block.BlockFace; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -16,16 +18,12 @@ import org.bukkit.event.player.PlayerInteractAtEntityEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerItemDamageEvent; +import org.bukkit.inventory.ItemStack; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; import java.util.concurrent.TimeUnit; public class BlocksListener implements Listener { - private static final Map lastClickedType = new HashMap<>(); - private final WildToolsPlugin plugin; public BlocksListener(WildToolsPlugin plugin) { @@ -47,9 +45,7 @@ public void onBlockBreak(BlockBreakEvent e) { if (tool == null) return; - String world = e.getBlock().getWorld().getName(); - - if (!tool.isWhitelistedWorld(world) || tool.isBlacklistedWorld(world)) { + if (!isWhitelistedWorld(tool, e.getBlock().getWorld())) { e.setCancelled(true); return; } @@ -99,9 +95,7 @@ public void onBlockInteract(PlayerInteractEvent e) { if (tool == null) return; - String world = e.getPlayer().getWorld().getName(); - - if (!tool.isWhitelistedWorld(world) || tool.isBlacklistedWorld(world)) { + if (!isWhitelistedWorld(tool, e.getPlayer().getWorld())) { e.setCancelled(true); return; } @@ -184,9 +178,7 @@ public void onEntityInteract(PlayerInteractAtEntityEvent e) { if (tool == null) return; - String world = e.getRightClicked().getWorld().getName(); - - if (!tool.isWhitelistedWorld(world) || tool.isBlacklistedWorld(world)) { + if (!isWhitelistedWorld(tool, e.getRightClicked().getWorld())) { e.setCancelled(true); return; } @@ -223,47 +215,47 @@ public void onEntityInteract(PlayerInteractAtEntityEvent e) { @EventHandler(priority = EventPriority.LOWEST) public void onOmniInteract(PlayerInteractEvent e) { - if (e.getAction() != Action.LEFT_CLICK_BLOCK) + if (e.getAction() != Action.LEFT_CLICK_BLOCK) { return; + } - Material blockType = e.getClickedBlock().getType(); + ItemStack handItem = plugin.getNMSAdapter().getItemInHand(e.getPlayer(), e); - if (lastClickedType.get(e.getPlayer().getUniqueId()) == blockType) + if (handItem == null || handItem.getType() == Material.AIR) { return; + } - ToolItemStack toolItemStack = ToolItemStack.of(plugin.getNMSAdapter().getItemInHand(e.getPlayer(), e)); + ToolItemStack toolItemStack = ToolItemStack.of(handItem); Tool tool = toolItemStack.getTool(); - if (tool == null || !tool.isOmni()) + if (tool == null || !tool.isOmni()) { return; + } - String world = e.getClickedBlock().getWorld().getName(); - - if (!tool.isWhitelistedWorld(world) || tool.isBlacklistedWorld(world)) { + if (!isWhitelistedWorld(tool, e.getClickedBlock().getWorld())) { e.setCancelled(true); return; } - lastClickedType.put(e.getPlayer().getUniqueId(), blockType); + Material toolType = toolItemStack.getType(); + Material blockType = e.getClickedBlock().getType(); + DestroySpeedCategory destroySpeedCategory = plugin.getNMSAdapter().getDestroySpeedCategory(blockType); - String replaceTypeName; + if (OmniToolHelper.isAlreadyCorrectToolType(toolType, destroySpeedCategory)) { + return; + } + + Material newToolType = OmniToolHelper.getNewToolType(toolType, destroySpeedCategory); - switch (plugin.getNMSAdapter().getDestroySpeedCategory(blockType)) { - case AXE: - replaceTypeName = "AXE"; - break; - case SHOVEL: - replaceTypeName = ServerVersion.isLegacy() ? "SPADE" : "SHOVEL"; - break; - default: - replaceTypeName = "PICKAXE"; - break; + if (toolType != newToolType) { + toolItemStack.setType(newToolType); } + } - Material replaceType = Material.valueOf(toolItemStack.getType().name().split("_")[0] + "_" + replaceTypeName); + private boolean isWhitelistedWorld(Tool tool, World world) { + String worldName = world.getName(); - if (toolItemStack.getType() != replaceType) - toolItemStack.setType(replaceType); + return tool.isWhitelistedWorld(worldName) && !tool.isBlacklistedWorld(worldName); } private String getTime(long timeLeft) { diff --git a/src/main/java/com/bgsoftware/wildtools/utils/Materials.java b/src/main/java/com/bgsoftware/wildtools/utils/Materials.java index c5c8152c..ff4a862b 100644 --- a/src/main/java/com/bgsoftware/wildtools/utils/Materials.java +++ b/src/main/java/com/bgsoftware/wildtools/utils/Materials.java @@ -29,6 +29,7 @@ public enum Materials { LIGHT_BLUE_STAINED_GLASS_PANE("STAINED_GLASS_PANE", 3), ENCHANTED_GOLDEN_APPLE("GOLDEN_APPLE", 1); + private static final EnumSet TOOLS = EnumSet.noneOf(Material.class); private static final Map> MATERIAL_TAGS = initializeMaterialTags(); private static int farmlandId = -1; @@ -105,6 +106,22 @@ public static boolean isForceUpdate(Material material) { return hasMaterialTag(material, Tag.FORCE_UPDATE); } + public static boolean isAxe(Material material) { + return hasMaterialTag(material, Tag.AXE); + } + + public static boolean isHoe(Material material) { + return hasMaterialTag(material, Tag.HOE); + } + + public static boolean isPickaxe(Material material) { + return hasMaterialTag(material, Tag.PICKAXE); + } + + public static boolean isShovel(Material material) { + return hasMaterialTag(material, Tag.SHOVEL); + } + private static boolean hasMaterialTag(Material material, Tag tag) { EnumSet tags = MATERIAL_TAGS.get(material); return tags != null && tags.contains(tag); @@ -117,6 +134,10 @@ public static int getFarmlandId() { return farmlandId; } + public static EnumSet getTools() { + return TOOLS; + } + public static Optional getSafeMaterial(String name) { try { return Optional.of(Material.valueOf(name)); @@ -185,6 +206,22 @@ private static Map> initializeMaterialTags() { if (materialName.contains("BUCKET")) { tags.add(Tag.BUCKET); } + if (materialName.endsWith("_AXE")) { + tags.add(Tag.AXE); + TOOLS.add(material); + } + if (materialName.endsWith("_HOE")) { + tags.add(Tag.HOE); + TOOLS.add(material); + } + if (materialName.endsWith("_PICKAXE")) { + tags.add(Tag.PICKAXE); + TOOLS.add(material); + } + if (ServerVersion.isLegacy() ? materialName.endsWith("_SPADE") : materialName.endsWith("_SHOVEL")) { + tags.add(Tag.SHOVEL); + TOOLS.add(material); + } if (!tags.isEmpty()) materialTags.put(material, tags); @@ -207,7 +244,11 @@ private enum Tag { BOTTLE, BUCKET, BLACKLISTED_BLOCK, - FORCE_UPDATE + FORCE_UPDATE, + AXE, + HOE, + PICKAXE, + SHOVEL, } diff --git a/src/main/java/com/bgsoftware/wildtools/utils/items/DestroySpeedCategory.java b/src/main/java/com/bgsoftware/wildtools/utils/items/DestroySpeedCategory.java index 7bc02f0d..2a5add68 100644 --- a/src/main/java/com/bgsoftware/wildtools/utils/items/DestroySpeedCategory.java +++ b/src/main/java/com/bgsoftware/wildtools/utils/items/DestroySpeedCategory.java @@ -3,6 +3,7 @@ public enum DestroySpeedCategory { AXE, + HOE, SHOVEL, PICKAXE diff --git a/src/main/java/com/bgsoftware/wildtools/utils/items/OmniToolHelper.java b/src/main/java/com/bgsoftware/wildtools/utils/items/OmniToolHelper.java new file mode 100644 index 00000000..88e459f2 --- /dev/null +++ b/src/main/java/com/bgsoftware/wildtools/utils/items/OmniToolHelper.java @@ -0,0 +1,63 @@ +package com.bgsoftware.wildtools.utils.items; + +import com.bgsoftware.wildtools.utils.Materials; +import com.bgsoftware.wildtools.utils.ServerVersion; +import org.bukkit.Material; + +import java.util.EnumMap; + +public class OmniToolHelper { + + private static final EnumMap> TOOL_TYPE_CACHE = new EnumMap<>(Material.class); + + static { + String shovelSuffix = ServerVersion.isLegacy() ? "SPADE" : "SHOVEL"; + + for (Material material : Materials.getTools()) { + String toolName = material.name(); + int lastUnderscoreIndex = toolName.lastIndexOf('_'); + + if (lastUnderscoreIndex != -1) { + String prefix = toolName.substring(0, lastUnderscoreIndex + 1); + + EnumMap categoryMap = new EnumMap<>(DestroySpeedCategory.class); + + categoryMap.put(DestroySpeedCategory.AXE, Materials.getSafeMaterial(prefix + "AXE").orElse(material)); + categoryMap.put(DestroySpeedCategory.HOE, Materials.getSafeMaterial(prefix + "HOE").orElse(material)); + categoryMap.put(DestroySpeedCategory.SHOVEL, Materials.getSafeMaterial(prefix + shovelSuffix).orElse(material)); + categoryMap.put(DestroySpeedCategory.PICKAXE, Materials.getSafeMaterial(prefix + "PICKAXE").orElse(material)); + + TOOL_TYPE_CACHE.put(material, categoryMap); + } + } + } + + private OmniToolHelper() { + } + + public static void init() { + // Do nothing. + } + + public static boolean isAlreadyCorrectToolType(Material toolType, DestroySpeedCategory destroySpeedCategory) { + switch (destroySpeedCategory) { + case AXE: + return Materials.isAxe(toolType); + case HOE: + return Materials.isHoe(toolType); + case SHOVEL: + return Materials.isShovel(toolType); + case PICKAXE: + return Materials.isPickaxe(toolType); + default: + return false; + } + } + + public static Material getNewToolType(Material toolType, DestroySpeedCategory category) { + EnumMap categoryMap = TOOL_TYPE_CACHE.get(toolType); + + return categoryMap != null ? categoryMap.get(category) : toolType; + } + +}