Compare commits

..
2 Commits
Author SHA1 Message Date
YouHaveTrouble 8616a74f33 first working version of tunnelling 2026-09-27 21:18:23 +02:00
YouHaveTrouble b573192990 some work on tunnelling enchant 2026-09-25 19:43:45 +02:00
9 changed files with 3632 additions and 2413 deletions
+3 -3
View File
@@ -10,13 +10,13 @@ jobs:
build-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up JDK
uses: actions/setup-java@v6
uses: actions/setup-java@v3
with:
java-version: '21'
java-version: 21
distribution: 'temurin'
- name: Set short commit hash
run: fullCommit=${{ github.sha }} && echo "SHORT_SHA=${fullCommit:0:8}" >> $GITHUB_ENV
+4 -4
View File
@@ -16,12 +16,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v7
uses: actions/checkout@v4
- name: Build Astro page
uses: withastro/action@v6
uses: withastro/action@v4
with:
path: ./docs
node-version: '24'
node-version: '22'
deploy:
needs: build
runs-on: ubuntu-latest
@@ -31,4 +31,4 @@ jobs:
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v5
uses: actions/deploy-pages@v4
+1 -1
View File
@@ -11,7 +11,7 @@ export default defineConfig({
sidebar: [
{
label: 'Documentation',
items: [{ autogenerate: { "directory": "documentation" } }]
autogenerate: { directory: 'documentation' },
},
{
label: 'Configuration',
+3555 -2326
View File
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -10,7 +10,8 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/starlight": "^0.42.4",
"astro": "^7.2.10"
"@astrojs/starlight": "^0.34.3",
"astro": "^5.6.1",
"sharp": "^0.32.5"
}
}
@@ -4,41 +4,11 @@ description: How to specify common input types in configuration
---
## Tags
### Items
#### Item reference
Example: `minecraft:stick`
For specific items, use namespaced vanilla item id. If namespace is not provided, `minecraft` is assumed.
#### Item tag
Example: `#minecraft:axes`
For <a href="https://minecraft.wiki/w/Item_tag_(Java_Edition)" target="_blank">item tags</a>, use namespaced tag id. If
namespace is not provided, `minecraft` is assumed. Custom tags from other plugins and datapacks are also supported.
### Blocks
#### Block reference
Example: `minecraft:dirt`
For specific items, use namespaced vanilla item id. If namespace is not provided, `minecraft` is assumed.
#### Block tag
Example: `#minecraft:planks`
For <a href="https://minecraft.wiki/w/Block_tag_(Java_Edition)" target="_blank">block tags</a>, use namespaced tag id. If
namespace is not provided, `minecraft` is assumed. Custom tags from other plugins and datapacks are also supported.
### Enchantments
#### Enchantment tag
Example: `#minecraft:in_enchanting_table`
For <a href="https://minecraft.wiki/w/Enchantment_tag_(Java_Edition)" target="_blank">enchantment tags</a>, use namespaced tag id. If
namespace is not provided, `minecraft` is assumed. Custom tags from other plugins and datapacks are also supported.
There are 2 types of tags that can be used in the configuration:
- `minecraft:item_name` - For specific items, use namespaced vanilla item id. If namespace is not provided, `minecraft` is assumed.
- `#minecraft:item_tag_name` - For <a href="https://minecraft.wiki/w/Item_tag_(Java_Edition)" target="_blank">item tags</a>,
use namespaced tag id. If namespace is not provided, `minecraft` is assumed. Custom tags from other plugins and
datapacks are also supported.
## Slot types
- `ANY` - Any slot.
@@ -18,8 +18,8 @@ Cost that will be added to the item when adding the enchantment to it in anvil.
- **Type**: `int`
Weight of the enchantment. Higher numbers mean it will come up more frequently in the enchanting table. Used if
`#minecraft:in_enchanting_table` is present in enchantment tags.
Weight of the enchantment. Used if `canGetFromEnchantingTable` is set to true. Higher numbers mean it will come up more
frequently in the enchanting table.
### minimumCost
@@ -29,7 +29,7 @@ Minimum cost that will be required for the enchantment to show up in the enchant
- **Type**: `int`
Base cost of the enchantment.
Base cost of the enchant.
#### perLevel
@@ -45,7 +45,7 @@ Maximum cost that will be required for the enchantment to show up in the enchant
- **Type**: `int`
Base cost of the enchantment.
Base cost of the enchant.
#### perLevel
@@ -55,22 +55,23 @@ Cost to add per level of the enchantment.
### enchantmentTags
- **Type**: [`Enchantment Tags`](/configuration/input-types/#enchantment-tag)
- **Type**: `key[]`
This is list of tags that the enchantment will be tagged with. This can be used to put the enchantment in enchanting table,
mark it as a curse, etc.
This is list of [tags](/configuration/input-types#tags) that the enchantment will be tagged with. This can be used to put the enchantment in enchanting table,
mark it as a curse, etc. <a href="https://minecraft.wiki/w/Enchantment_tag_(Java_Edition)" target="_blank">All vanilla</a>
and custom tags are supported.
### supportedItemTags
- **Type**: [`Item Tags`](/configuration/input-types/#items)
- **Type**: `key[]`
Items and/or item tags that the enchantment can be applied to.
[Items and/or item tags](/configuration/input-types#tags) that the enchantment can be applied to.
### activeSlots
- **Type**: [`Slot types`](/configuration/input-types/#slot-types)
- **Type**: `string[]`
Inventory slots that the enchantment will be active in.
[Slots](/configuration/input-types#slot-types) that the enchantment will be active in.
### enabled
@@ -95,11 +96,9 @@ of the enchantment does not support multiple levels.
## Telepathy
### onlyUserCanPickupItems
- **Type**: `boolean`
If set to true, items teleported by the enchantment will only be able to be picked up by the player that broke the block.
If set to true, items teleported by the enchant will only be able to be picked up by the player that broke the block.
## Executioner
@@ -25,6 +25,7 @@ public class TunnellingEnchant implements EnchantioEnchant {
public static final Key AFFECTED_BLOCKS_KEY = Key.key("enchantio", "affected_by_tunnelling");
private final int anvilCost, weight, maxLevel, blocksPerLevel;
private final boolean canBreakToolIncompatibleBlocks;
private final EnchantmentRegistryEntry.EnchantmentCost minimumCost;
private final EnchantmentRegistryEntry.EnchantmentCost maximumCost;
private final Set<TagEntry<ItemType>> supportedItemTags = new HashSet<>();
@@ -40,7 +41,8 @@ public class TunnellingEnchant implements EnchantioEnchant {
Collection<TagEntry<ItemType>> supportedItemTags,
Map<Key, Set<TagEntry<BlockType>>> affectedBlockTags,
int maxLevel,
int blocksPerLevel
int blocksPerLevel,
boolean canBreakToolIncompatibleBlocks
) {
this.anvilCost = anvilCost;
this.weight = weight;
@@ -48,6 +50,7 @@ public class TunnellingEnchant implements EnchantioEnchant {
this.maximumCost = maximumCost;
this.maxLevel = maxLevel;
this.blocksPerLevel = blocksPerLevel;
this.canBreakToolIncompatibleBlocks = canBreakToolIncompatibleBlocks;
this.supportedItemTags.addAll(supportedItemTags);
this.enchantTagKeys.addAll(enchantTagKeys);
this.affectedBlockTags.putAll(affectedBlockTags);
@@ -112,6 +115,10 @@ public class TunnellingEnchant implements EnchantioEnchant {
return blocksPerLevel;
}
public boolean canBreakToolIncompatibleBlocks() {
return canBreakToolIncompatibleBlocks;
}
public static TunnellingEnchant create(ConfigurationSection configurationSection) {
TunnellingEnchant tunnellingEnchant = new TunnellingEnchant(
EnchantioConfig.getInt(configurationSection, "anvilCost", 1),
@@ -145,18 +152,13 @@ public class TunnellingEnchant implements EnchantioEnchant {
"#minecraft:base_stone_overworld",
"#minecraft:base_stone_nether",
"#minecraft:ores",
"#minecraft:terracotta",
"#minecraft:glazed_terracotta",
"#minecraft:concrete",
"#minecraft:stone_bricks",
"minecraft:end_stone",
"minecraft:cobblestone",
"minecraft:cobbled_deepslate"
"minecraft:end_stone"
)
))
),
EnchantioConfig.getInt(configurationSection, "maxLevel", 1),
EnchantioConfig.getInt(configurationSection, "blocksPerLevel", 1)
EnchantioConfig.getInt(configurationSection, "blocksPerLevel", 1),
EnchantioConfig.getBoolean(configurationSection, "canBreakToolIncompatibleBlocks", false)
);
if (EnchantioConfig.getBoolean(configurationSection, "enabled", true)) {
@@ -3,6 +3,7 @@ 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.Enchantio;
import me.youhavetrouble.enchantio.EnchantioConfig;
import me.youhavetrouble.enchantio.enchants.EnchantioEnchant;
import me.youhavetrouble.enchantio.enchants.TunnellingEnchant;
@@ -21,7 +22,9 @@ import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataType;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@SuppressWarnings("UnstableApiUsage")
@@ -38,7 +41,7 @@ public class TunnellingListener implements Listener {
if (event.getHand() != EquipmentSlot.HAND) return;
if (event.getAction() != Action.LEFT_CLICK_BLOCK) return;
Player player = event.getPlayer();
if (GameMode.CREATIVE.equals(player.getGameMode())) return;
if (player.isSneaking() || GameMode.CREATIVE.equals(player.getGameMode())) return;
ItemStack item = event.getItem();
if (item == null) return;
if (!item.containsEnchantment(tunnelling)) return;
@@ -71,29 +74,33 @@ public class TunnellingListener implements Listener {
Set<Block> blocksToBreak = getSquare(block, blockFace, tunnellingEnchant.getBlocksPerLevel() * enchantLevel);
blockBreakSkips.addAll(blocksToBreak);
for (Block b : blocksToBreak) {
if (player.getInventory().getItemInMainHand().isEmpty()) {
event.setCancelled(true);
blockBreakSkips.removeAll(blocksToBreak);
break;
}
event.getPlayer().breakBlock(b);
BlockBreakEvent breakEvent = new BlockBreakEvent(b, player);
Enchantio.getPlugin(Enchantio.class).getServer().getPluginManager().callEvent(breakEvent);
blockBreakSkips.remove(b);
breakBlock(breakEvent, tunnellingEnchant);
}
}
private Set<Block> getSquare(Block block, BlockFace face, int range) {
Set<Block> blocks = new HashSet<>();
switch (face) {
case DOWN, UP -> {
return getBlocksToTunnel(block.getLocation(), range, 0, range);
}
case EAST, WEST -> {
return getBlocksToTunnel(block.getLocation(), 0, range, range);
}
case NORTH, SOUTH -> {
return getBlocksToTunnel(block.getLocation(), range, range, 0);
}
case DOWN:
case UP:
blocks.addAll(getBlocksToTunnel(block.getLocation(), range, 0, range));
break;
case EAST:
case WEST:
blocks.addAll(getBlocksToTunnel(block.getLocation(), 0, range, range));
break;
case NORTH:
case SOUTH:
blocks.addAll(getBlocksToTunnel(block.getLocation(), range, range, 0));
break;
default:
break;
}
return new HashSet<>();
return blocks;
}
/**
@@ -101,8 +108,8 @@ public class TunnellingListener implements Listener {
* @param base location at the centre of selection
* @return All blocks that will get broken
*/
private Set<Block> getBlocksToTunnel(Location base, int changeX, int changeY, int changeZ) {
Set<Block> blocks = new HashSet<>();
private List<Block> getBlocksToTunnel(Location base, int changeX, int changeY, int changeZ) {
List<Block> blocks = new ArrayList<>();
for (int x = (base.getBlockX() - changeX); x <= (base.getBlockX() + changeX); x++) {
for (int y = (base.getBlockY() - changeY); y <= (base.getBlockY() + changeY); y++) {
for (int z = (base.getBlockZ() - changeZ); z <= (base.getBlockZ() + changeZ); z++) {
@@ -119,4 +126,15 @@ public class TunnellingListener implements Listener {
return blocks;
}
private void breakBlock(BlockBreakEvent event, TunnellingEnchant enchant) {
if (tunnelling == null) return;
if (event.isCancelled()) return;
Block block = event.getBlock();
ItemStack item = event.getPlayer().getInventory().getItemInMainHand();
int enchantLevel = item.getEnchantmentLevel(tunnelling);
if (enchantLevel <= 0) return;
block.breakNaturally(item, true, event.getExpToDrop() > 0, enchant.canBreakToolIncompatibleBlocks());
item.damage(1, event.getPlayer());
}
}