some work on tunnelling enchant

This commit is contained in:
2026-09-25 19:43:45 +02:00
parent 85585b14d6
commit b573192990
3 changed files with 238 additions and 0 deletions
@@ -2,12 +2,14 @@ package me.youhavetrouble.enchantio;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import io.papermc.paper.registry.keys.tags.BlockTypeTagKeys;
import io.papermc.paper.registry.keys.tags.EnchantmentTagKeys;
import io.papermc.paper.registry.keys.tags.ItemTypeTagKeys;
import io.papermc.paper.registry.tag.TagKey;
import io.papermc.paper.tag.TagEntry;
import me.youhavetrouble.enchantio.enchants.*;
import net.kyori.adventure.key.Key;
import org.bukkit.block.BlockType;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
@@ -210,6 +212,32 @@ public class EnchantioConfig {
return enchantTagKeys;
}
public static Set<TagEntry<BlockType>> getBlockTagKeysFromList(@NotNull List<String> tags) {
Set<TagEntry<BlockType>> blockTagKeys = new HashSet<>();
for (String blockTag : tags) {
if (blockTag == null) continue;
if (blockTag.startsWith("#")) {
blockTag = blockTag.substring(1);
try {
Key key = Key.key(blockTag);
TagKey<BlockType> tagKey = BlockTypeTagKeys.create(key);
TagEntry<BlockType> tagEntry = TagEntry.tagEntry(tagKey);
blockTagKeys.add(tagEntry);
} catch (IllegalArgumentException ignored) {
}
continue;
}
try {
Key key = Key.key(blockTag);
TagKey<BlockType> tagKey = BlockTypeTagKeys.create(key);
TagEntry<BlockType> tagEntry = TagEntry.tagEntry(tagKey);
blockTagKeys.add(tagEntry);
} catch (IllegalArgumentException | NullPointerException ignored) {
}
}
return blockTagKeys;
}
public static ConfigurationSection getConfigSection(ConfigurationSection section, String key) {
ConfigurationSection value = section.getConfigurationSection(key);
if (value == null) {
@@ -0,0 +1,147 @@
package me.youhavetrouble.enchantio.enchants;
import io.papermc.paper.registry.data.EnchantmentRegistryEntry;
import io.papermc.paper.registry.tag.TagKey;
import io.papermc.paper.tag.TagEntry;
import me.youhavetrouble.enchantio.EnchantioConfig;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.text.Component;
import org.bukkit.block.BlockType;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.EquipmentSlotGroup;
import org.bukkit.inventory.ItemType;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import static me.youhavetrouble.enchantio.EnchantioConfig.ENCHANTS;
@SuppressWarnings("UnstableApiUsage")
public class TunnellingEnchant implements EnchantioEnchant {
public static final Key KEY = Key.key("enchantio:tunnelling");
private final int anvilCost, weight, maxLevel;
private final EnchantmentRegistryEntry.EnchantmentCost minimumCost;
private final EnchantmentRegistryEntry.EnchantmentCost maximumCost;
private final Set<TagEntry<ItemType>> supportedItemTags = new HashSet<>();
private final Set<TagKey<Enchantment>> enchantTagKeys = new HashSet<>();
private final Set<TagEntry<BlockType>> blockTagKeys = new HashSet<>();
public TunnellingEnchant(
int anvilCost,
int weight,
EnchantmentRegistryEntry.EnchantmentCost minimumCost,
EnchantmentRegistryEntry.EnchantmentCost maximumCost,
Collection<TagKey<Enchantment>> enchantTagKeys,
Collection<TagEntry<ItemType>> supportedItemTags,
Collection<TagEntry<BlockType>> supportedBlockTags,
int maxLevel
) {
this.anvilCost = anvilCost;
this.weight = weight;
this.minimumCost = minimumCost;
this.maximumCost = maximumCost;
this.maxLevel = maxLevel;
this.supportedItemTags.addAll(supportedItemTags);
this.enchantTagKeys.addAll(enchantTagKeys);
this.blockTagKeys.addAll(supportedBlockTags);
}
@Override
public @NotNull Key getKey() {
return KEY;
}
@Override
public @NotNull Component getDescription() {
return Component.translatable("enchantio.enchant.tunnelling", "Tunnelling");
}
@Override
public int getAnvilCost() {
return anvilCost;
}
@Override
public int getMaxLevel() {
return maxLevel;
}
@Override
public int getWeight() {
return weight;
}
@Override
public EnchantmentRegistryEntry.@NotNull EnchantmentCost getMinimumCost() {
return minimumCost;
}
@Override
public EnchantmentRegistryEntry.@NotNull EnchantmentCost getMaximumCost() {
return maximumCost;
}
@Override
public @NotNull Iterable<EquipmentSlotGroup> getActiveSlots() {
return Set.of(EquipmentSlotGroup.MAINHAND);
}
@Override
public @NotNull Set<TagEntry<ItemType>> getSupportedItems() {
return supportedItemTags;
}
@Override
public @NotNull Set<TagKey<Enchantment>> getEnchantTagKeys() {
return Collections.unmodifiableSet(enchantTagKeys);
}
public static TunnellingEnchant create(ConfigurationSection configurationSection) {
TunnellingEnchant tunnellingEnchant = new TunnellingEnchant(
EnchantioConfig.getInt(configurationSection, "anvilCost", 1),
EnchantioConfig.getInt(configurationSection, "weight", 10),
EnchantmentRegistryEntry.EnchantmentCost.of(
EnchantioConfig.getInt(configurationSection, "minimumCost.base", 40),
EnchantioConfig.getInt(configurationSection, "minimumCost.additionalPerLevel", 3)
),
EnchantmentRegistryEntry.EnchantmentCost.of(
EnchantioConfig.getInt(configurationSection, "maximumCost.base", 65),
EnchantioConfig.getInt(configurationSection, "maximumCost.additionalPerLevel", 1)
),
EnchantioConfig.getEnchantmentTagKeysFromList(EnchantioConfig.getStringList(
configurationSection,
"enchantmentTags",
List.of("#in_enchanting_table")
)),
EnchantioConfig.getItemTagEntriesFromList(EnchantioConfig.getStringList(
configurationSection,
"supportedItemTags",
List.of(
"#minecraft:enchantable/mining"
)
)),
EnchantioConfig.getBlockTagKeysFromList(EnchantioConfig.getStringList(
configurationSection,
"mineableBlockTags",
List.of(
"#minecraft:base_stone_overworld",
"#minecraft:base_stone_nether",
"#minecraft:ores",
"minecraft:end_stone"
)
)),
EnchantioConfig.getInt(configurationSection, "maxLevel", 1)
);
if (EnchantioConfig.getBoolean(configurationSection, "enabled", true)) {
ENCHANTS.put(TunnellingEnchant.KEY, tunnellingEnchant);
}
return tunnellingEnchant;
}
}
@@ -0,0 +1,63 @@
package me.youhavetrouble.enchantio.listeners;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.keys.tags.BlockTypeTagKeys;
import me.youhavetrouble.enchantio.EnchantioConfig;
import me.youhavetrouble.enchantio.enchants.EnchantioEnchant;
import me.youhavetrouble.enchantio.enchants.TunnellingEnchant;
import org.bukkit.GameMode;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.block.Block;
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.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataType;
@SuppressWarnings("UnstableApiUsage")
public class TunnellingListener implements Listener {
private final Enchantment tunnelling = RegistryAccess.registryAccess().getRegistry(RegistryKey.ENCHANTMENT).get(TunnellingEnchant.KEY);
private final NamespacedKey tunnellingKey = new NamespacedKey("enchantio", "tunnelling");
private final NamespacedKey tunnellingBlockFaceKey = new NamespacedKey("enchantio", "tunellingblockface");
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onTunnelBlockSideCheck(PlayerInteractEvent event) {
if (tunnelling == null) return;
if (event.getHand() != EquipmentSlot.OFF_HAND) return;
if (event.getAction() != Action.LEFT_CLICK_BLOCK) return;
Player player = event.getPlayer();
if (player.isSneaking() || GameMode.CREATIVE.equals(player.getGameMode())) return;
ItemStack item = event.getItem();
if (item == null) return;
if (!item.containsEnchantment(tunnelling)) return;
event.getPlayer().getPersistentDataContainer().set(tunnellingBlockFaceKey, PersistentDataType.STRING, event.getBlockFace().toString());
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onTunnelBlockBreak(BlockBreakEvent event) {
if (tunnelling == null) return;
Player player = event.getPlayer();
if (GameMode.CREATIVE.equals(player.getGameMode())) return;
EnchantioEnchant enchant = EnchantioConfig.ENCHANTS.get(TunnellingEnchant.KEY);
if (!(enchant instanceof TunnellingEnchant tunnellingEnchant)) return;
ItemStack item = event.getPlayer().getInventory().getItemInMainHand();
if (!item.containsEnchantment(tunnelling)) return;
Block block = event.getBlock();
// TODO register a block tag and flatten it to check the block against it
Registry.BLOCK.getTagValues(BlockTypeTagKeys.create(tunnellingKey)).contains(block.getType().asBlockType());
}
}