diff --git a/veinminer-bukkit/src/main/java/wtf/choco/veinminer/block/VeinMinerBlock.java b/veinminer-bukkit/src/main/java/wtf/choco/veinminer/block/VeinMinerBlock.java index 5006ac0..46ea103 100644 --- a/veinminer-bukkit/src/main/java/wtf/choco/veinminer/block/VeinMinerBlock.java +++ b/veinminer-bukkit/src/main/java/wtf/choco/veinminer/block/VeinMinerBlock.java @@ -4,6 +4,8 @@ import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.Tag; import org.bukkit.block.data.BlockData; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -69,9 +71,7 @@ public default int compareTo(@Nullable VeinMinerBlock other) { } /** - * Get a {@link VeinMinerBlock} from a string. - * - * Example states: + * Get a {@link VeinMinerBlock} from a string. Example states: *
      * chest
      * minecraft:chest
@@ -79,6 +79,7 @@ public default int compareTo(@Nullable VeinMinerBlock other) {
      * minecraft:chest[facing=north,waterlogged=true]
      * * // The wildcard state
      * 
+ * This method will also support a tag key such as {@code #minecraft:leaves}. * * @param string the string from which to parse a VeinMinerBlock instance * @@ -90,6 +91,21 @@ public static VeinMinerBlock fromString(@NotNull String string) { return WILDCARD; } + if (string.startsWith("#")) { + // TODO: Use the new tag system + NamespacedKey tagKey = NamespacedKey.fromString(string.substring(1)); + if (tagKey == null) { + return null; + } + + Tag tag = Bukkit.getTag("blocks", tagKey, Material.class); + if (tag == null) { + return null; + } + + return new VeinMinerBlockTag(tag); + } + Matcher matcher = VeinMiner.PATTERN_BLOCK_STATE.matcher(string); if (!matcher.find()) { return null; diff --git a/veinminer-bukkit/src/main/java/wtf/choco/veinminer/block/VeinMinerBlockTag.java b/veinminer-bukkit/src/main/java/wtf/choco/veinminer/block/VeinMinerBlockTag.java new file mode 100644 index 0000000..7ade230 --- /dev/null +++ b/veinminer-bukkit/src/main/java/wtf/choco/veinminer/block/VeinMinerBlockTag.java @@ -0,0 +1,59 @@ +package wtf.choco.veinminer.block; + +import org.bukkit.Material; +import org.bukkit.Tag; +import org.bukkit.block.data.BlockData; +import org.jetbrains.annotations.NotNull; + +/** + * A type of {@link VeinMinerBlock} backed by a block {@link Tag}. + */ +public final class VeinMinerBlockTag implements VeinMinerBlock { + + private final Tag tag; + + /** + * Construct a new {@link VeinMinerBlockTag}. + * + * @param tag the block tag + */ + public VeinMinerBlockTag(Tag tag) { + this.tag = tag; + } + + public Tag getTag() { + return tag; + } + + @Override + public boolean matchesType(@NotNull Material type) { + return tag.isTagged(type); + } + + @Override + public boolean matchesState(@NotNull BlockData state, boolean exact) { + return matchesType(state.getMaterial()); + } + + @NotNull + @Override + public String toStateString() { + return "#" + tag.getKey().toString(); + } + + @Override + public int hashCode() { + return tag.getKey().hashCode(); + } + + @Override + public boolean equals(Object obj) { + return obj == this || (obj instanceof VeinMinerBlockTag other && tag.getKey().equals(other.tag.getKey())); + } + + @Override + public String toString() { + return String.format("VeinMinerBlockTag[type=\"%s\"]", tag.getKey().toString()); + } + +} diff --git a/veinminer-bukkit/src/main/java/wtf/choco/veinminer/command/CommandBlocklist.java b/veinminer-bukkit/src/main/java/wtf/choco/veinminer/command/CommandBlocklist.java index 4aa726c..1609ee6 100644 --- a/veinminer-bukkit/src/main/java/wtf/choco/veinminer/command/CommandBlocklist.java +++ b/veinminer-bukkit/src/main/java/wtf/choco/veinminer/command/CommandBlocklist.java @@ -59,7 +59,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command String blockArg = args[2].toLowerCase(); VeinMinerBlock block = VeinMinerBlock.fromString(blockArg); if (block == null) { - sender.sendMessage(ChatColor.RED + "Unknown block type/block state (was it an item)? " + ChatColor.GRAY + "Given " + ChatColor.YELLOW + blockArg + ChatColor.GRAY + "."); + sender.sendMessage(ChatColor.RED + "Unknown block type, state, or tag (was it an item)? " + ChatColor.GRAY + "Given " + ChatColor.YELLOW + blockArg + ChatColor.GRAY + "."); return true; } @@ -86,7 +86,7 @@ else if (args[1].equalsIgnoreCase("remove")) { String blockArg = args[2].toLowerCase(); VeinMinerBlock block = VeinMinerBlock.fromString(blockArg); if (block == null) { - sender.sendMessage(ChatColor.RED + "Unknown block type/block state (was it an item)? " + ChatColor.GRAY + "Given " + ChatColor.YELLOW + blockArg + ChatColor.GRAY + "."); + sender.sendMessage(ChatColor.RED + "Unknown block type, state, or tag (was it an item)? " + ChatColor.GRAY + "Given " + ChatColor.YELLOW + blockArg + ChatColor.GRAY + "."); return true; } diff --git a/veinminer-bukkit/src/main/java/wtf/choco/veinminer/pattern/PatternUtils.java b/veinminer-bukkit/src/main/java/wtf/choco/veinminer/pattern/PatternUtils.java index b79a287..4e14772 100644 --- a/veinminer-bukkit/src/main/java/wtf/choco/veinminer/pattern/PatternUtils.java +++ b/veinminer-bukkit/src/main/java/wtf/choco/veinminer/pattern/PatternUtils.java @@ -6,6 +6,7 @@ import wtf.choco.veinminer.block.BlockList; import wtf.choco.veinminer.block.VeinMinerBlock; +import wtf.choco.veinminer.block.VeinMinerBlockTag; import wtf.choco.veinminer.block.VeinMinerBlockWildcard; /** @@ -29,7 +30,7 @@ private PatternUtils() { } * false otherwise */ public static boolean typeMatches(@NotNull VeinMinerBlock block, @Nullable BlockList aliasList, @NotNull BlockData origin, @NotNull BlockData current) { - if (block instanceof VeinMinerBlockWildcard) { + if (block instanceof VeinMinerBlockWildcard || block instanceof VeinMinerBlockTag) { return origin.getMaterial() == current.getMaterial() || (aliasList != null && aliasList.containsState(current)); } diff --git a/veinminer-bukkit/src/main/resources/categories.yml b/veinminer-bukkit/src/main/resources/categories.yml index e71b936..5453243 100644 --- a/veinminer-bukkit/src/main/resources/categories.yml +++ b/veinminer-bukkit/src/main/resources/categories.yml @@ -3,7 +3,8 @@ # Block list values are 1:1 with in-game IDs. The prepending of "minecraft:" is optional. # To specify states, do so with [brackets] as you would in a vanilla /setblock command. For # example, "minecraft:chest[waterlogged=true]" will search for any waterlogged chests. Other -# undefined states will be ignored when checking. +# undefined states will be ignored when checking. Tag keys may also be specified if desired +# by prepending the key with a #. For example, '#minecraft:logs' will reference all log blocks. # # Each category may define any of the following options: # "RepairFriendly", "MaxVeinSize", "Cost", and "DisabledWorlds" @@ -108,61 +109,28 @@ Pickaxe: - 'minecraft:diamond_pickaxe' - 'minecraft:netherite_pickaxe' BlockList: + - '#minecraft:coal_ores' + - '#minecraft:copper_ores' + - '#minecraft:diamond_ores' + - '#minecraft:emerald_ores' + - '#minecraft:gold_ores' + - '#minecraft:iron_ores' + - '#minecraft:lapis_ores' + - '#minecraft:redstone_ores' - 'minecraft:amethyst_cluster' - 'minecraft:ancient_debris' - - 'minecraft:coal_ore' - - 'minecraft:copper_ore' - - 'minecraft:deepslate_coal_ore' - - 'minecraft:deepslate_copper_ore' - - 'minecraft:deepslate_diamond_ore' - - 'minecraft:deepslate_emerald_ore' - - 'minecraft:deepslate_gold_ore' - - 'minecraft:deepslate_iron_ore' - - 'minecraft:deepslate_lapis_ore' - - 'minecraft:deepslate_redstone_ore' - - 'minecraft:diamond_ore' - - 'minecraft:emerald_ore' - - 'minecraft:gold_ore' - - 'minecraft:iron_ore' - - 'minecraft:lapis_ore' - - 'minecraft:nether_gold_ore' - 'minecraft:nether_quartz_ore' - 'minecraft:raw_copper_block' - 'minecraft:raw_gold_block' - 'minecraft:raw_iron_block' - - 'minecraft:redstone_ore' Shears: Items: - 'minecraft:shears' BlockList: - - 'minecraft:acacia_leaves' - - 'minecraft:azalea_leaves' - - 'minecraft:birch_leaves' - - 'minecraft:black_wool' - - 'minecraft:blue_wool' - - 'minecraft:brown_wool' - - 'minecraft:cherry_leaves' + - '#minecraft:leaves' + - '#minecraft:wool' - 'minecraft:cobweb' - - 'minecraft:cyan_wool' - - 'minecraft:dark_oak_leaves' - - 'minecraft:flowering_azalea_leaves' - - 'minecraft:gray_wool' - - 'minecraft:green_wool' - - 'minecraft:jungle_leaves' - - 'minecraft:light_blue_wool' - - 'minecraft:light_gray_wool' - - 'minecraft:lime_wool' - - 'minecraft:magenta_wool' - - 'minecraft:mangrove_leaves' - - 'minecraft:oak_leaves' - - 'minecraft:orange_wool' - - 'minecraft:pink_wool' - - 'minecraft:purple_wool' - - 'minecraft:red_wool' - - 'minecraft:spruce_leaves' - - 'minecraft:white_wool' - - 'minecraft:yellow_wool' Shovel: Items: