Skip to content

Commit

Permalink
Preliminary support for tags in block lists (closes #100)
Browse files Browse the repository at this point in the history
I still think this feature should wait until Bukkit's Tag API is improved and BlockType and ItemType are better integrated into the API. But for now this should at least work as expected.
  • Loading branch information
2008Choco committed Nov 9, 2024
1 parent 5227c15 commit 8f40ea1
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -69,16 +71,15 @@ 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:
* <pre>
* chest
* minecraft:chest
* minecraft:chest[waterlogged=true]
* minecraft:chest[facing=north,waterlogged=true]
* * // The wildcard state
* </pre>
* This method will also support a tag key such as {@code #minecraft:leaves}.
*
* @param string the string from which to parse a VeinMinerBlock instance
*
Expand All @@ -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<Material> 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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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<Material> tag;

/**
* Construct a new {@link VeinMinerBlockTag}.
*
* @param tag the block tag
*/
public VeinMinerBlockTag(Tag<Material> tag) {
this.tag = tag;
}

public Tag<Material> 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());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand All @@ -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));
}

Expand Down
56 changes: 12 additions & 44 deletions veinminer-bukkit/src/main/resources/categories.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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:
Expand Down

0 comments on commit 8f40ea1

Please sign in to comment.