From 41c1ed38414d6ac0b5b8b15d3f07e39da5b8eded Mon Sep 17 00:00:00 2001 From: halogly Date: Sun, 31 Aug 2025 15:36:57 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=BA=A4=E4=BA=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/item/behavior/AxeItemBehavior.java | 5 +- .../behavior/FlintAndSteelItemBehavior.java | 7 +- .../item/listener/ItemEventListener.java | 9 +- .../bukkit/util/InteractUtils.java | 1376 +++++++++++++---- .../craftengine/core/block/BlockKeys.java | 265 ++-- .../core/entity/EntityTypeKeys.java | 1 + .../craftengine/core/item/ItemKeys.java | 33 +- .../momirealms/craftengine/core/util/Key.java | 15 + 8 files changed, 1307 insertions(+), 404 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/AxeItemBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/AxeItemBehavior.java index e928f9233..af61198c2 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/AxeItemBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/AxeItemBehavior.java @@ -108,7 +108,10 @@ public class AxeItemBehavior extends ItemBehavior { if (!InteractUtils.isInteractable( bukkitPlayer, BlockStateUtils.fromBlockData(customState.vanillaBlockState().literalObject()), context.getHitResult(), item - ) || player.isSecondaryUseActive()) { + ) || (player.isSecondaryUseActive() && !InteractUtils.isIgnoreSneaking( + bukkitPlayer, BlockStateUtils.fromBlockData(customState.vanillaBlockState().literalObject()), + context.getHitResult(), item + ))) { player.swingHand(context.getHand()); } // shrink item amount diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/FlintAndSteelItemBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/FlintAndSteelItemBehavior.java index 2be578ff4..c397786d1 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/FlintAndSteelItemBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/FlintAndSteelItemBehavior.java @@ -88,8 +88,9 @@ public class FlintAndSteelItemBehavior extends ItemBehavior { context.getHitResult(), (Item) context.getItem())) { return InteractionResult.PASS; } - // 且没有shift - if (!player.isSecondaryUseActive()) { + // 且没有shift或者忽略潜行的可交互方块 + if (!player.isSecondaryUseActive() || InteractUtils.isIgnoreSneaking((Player) player.platformPlayer(), vanillaBlockState, + context.getHitResult(), (Item) context.getItem())) { player.playSound(FLINT_SOUND, firePos, SoundSource.BLOCK, 1f, RandomUtils.generateRandomFloat(0.8f, 1.2f)); } } else { @@ -110,7 +111,7 @@ public class FlintAndSteelItemBehavior extends ItemBehavior { // 客户端觉得这玩意可交互,就会忽略声音 if (InteractUtils.isInteractable((Player) player.platformPlayer(), vanillaBlockState, context.getHitResult(), (Item) context.getItem())) { // 如果按住了shift,则代表尝试对侧面方块点火 - if (player.isSecondaryUseActive()) { + if (player.isSecondaryUseActive() && !InteractUtils.isIgnoreSneaking((Player) player.platformPlayer(), vanillaBlockState, context.getHitResult(), (Item) context.getItem())) { // 如果底部不能燃烧,则燃烧点位为侧面,需要补发 if (!belowCanBurn) { player.playSound(FLINT_SOUND, firePos, SoundSource.BLOCK, 1f, RandomUtils.generateRandomFloat(0.8f, 1.2f)); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java index ce1500a38..653679a9d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java @@ -257,7 +257,7 @@ public class ItemEventListener implements Listener { // so we should check and resend sounds on BlockPlaceEvent BlockData craftBlockData = BlockStateUtils.fromBlockData(immutableBlockState.vanillaBlockState().literalObject()); if (InteractUtils.isInteractable(player, craftBlockData, hitResult, itemInHand)) { - if (!serverPlayer.isSecondaryUseActive()) { + if (!serverPlayer.isSecondaryUseActive() || InteractUtils.isIgnoreSneaking(player, craftBlockData, hitResult, itemInHand)) { serverPlayer.setResendSound(); } } else { @@ -276,7 +276,7 @@ public class ItemEventListener implements Listener { return; } else { // todo 实际上这里的处理并不正确,因为判断玩家是否能够放置那个方块需要更加细节的判断。比如玩家无法对着树叶放置火把,但是交互事件依然触发,此情况下不可丢弃自定义行为。 - if (serverPlayer.isSecondaryUseActive() || !InteractUtils.isInteractable(player, blockData, hitResult, itemInHand)) { + if ((serverPlayer.isSecondaryUseActive() && InteractUtils.isIgnoreSneaking(player, blockData, hitResult, itemInHand)) || !InteractUtils.isInteractable(player, blockData, hitResult, itemInHand)) { event.setCancelled(true); } } @@ -290,9 +290,10 @@ public class ItemEventListener implements Listener { if (optionalItemBehaviors.isPresent()) { // 检测是否可交互应当只判断原版方块,因为自定义方块早就判断过了,如果可交互不可能到这一步 boolean interactable = immutableBlockState == null && InteractUtils.isInteractable(player, blockData, hitResult, itemInHand); + boolean isIgnoreSneaking = InteractUtils.isIgnoreSneaking(player, blockData, hitResult, itemInHand); // 如果方块可交互但是玩家没shift,那么原版的方块交互优先,取消自定义物品的behavior // todo 如果我的物品行为允许某些交互呢?是否值得进一步处理? - if (!serverPlayer.isSecondaryUseActive() && interactable) { + if ((!serverPlayer.isSecondaryUseActive() || isIgnoreSneaking) && interactable) { return; } UseOnContext useOnContext = new UseOnContext(serverPlayer, hand, itemInHand, hitResult); @@ -315,7 +316,7 @@ public class ItemEventListener implements Listener { // 执行物品右键事件 if (hasCustomItem) { // 要求服务端侧这个方块不可交互,或玩家处于潜行状态 - if (serverPlayer.isSecondaryUseActive() || !InteractUtils.isInteractable(player, blockData, hitResult, itemInHand)) { + if ((serverPlayer.isSecondaryUseActive() && !InteractUtils.isIgnoreSneaking(player, blockData, hitResult, itemInHand)) || !InteractUtils.isInteractable(player, blockData, hitResult, itemInHand)) { Cancellable dummy = Cancellable.dummy(); PlayerOptionalContext context = PlayerOptionalContext.of(serverPlayer, ContextHolder.builder() .withParameter(DirectContextParameters.BLOCK, new BukkitExistingBlock(block)) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/InteractUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/InteractUtils.java index dee6874b7..06f112fb5 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/InteractUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/InteractUtils.java @@ -4,11 +4,13 @@ import io.papermc.paper.entity.Shearable; import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.item.behavior.BlockItemBehavior; import net.momirealms.craftengine.bukkit.item.recipe.BukkitRecipeManager; +import net.momirealms.craftengine.bukkit.world.BukkitWorld; import net.momirealms.craftengine.core.block.BlockKeys; import net.momirealms.craftengine.core.entity.EntityTypeKeys; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemKeys; import net.momirealms.craftengine.core.item.behavior.ItemBehavior; +import net.momirealms.craftengine.core.item.modifier.AttributeModifiersModifier; import net.momirealms.craftengine.core.item.recipe.RecipeType; import net.momirealms.craftengine.core.item.recipe.UniqueIdItem; import net.momirealms.craftengine.core.item.recipe.input.SingleItemInput; @@ -20,12 +22,14 @@ import net.momirealms.craftengine.core.util.QuadFunction; import net.momirealms.craftengine.core.util.TriFunction; import net.momirealms.craftengine.core.world.BlockHitResult; import net.momirealms.craftengine.core.world.BlockPos; -import org.bukkit.GameMode; +import net.momirealms.craftengine.core.world.ExistingBlock; +import org.bukkit.*; +import org.bukkit.attribute.Attribute; +import org.bukkit.attribute.AttributeInstance; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Levelled; -import org.bukkit.block.data.type.Bell; -import org.bukkit.block.data.type.ChiseledBookshelf; -import org.bukkit.block.data.type.RespawnAnchor; +import org.bukkit.block.data.Lightable; +import org.bukkit.block.data.type.*; import org.bukkit.entity.*; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; @@ -38,75 +42,132 @@ import java.util.Optional; public final class InteractUtils { private static final Map, BlockData, BlockHitResult, Boolean>> INTERACTIONS = new HashMap<>(); + private static final Map, BlockData, BlockHitResult, Boolean>> SNEAK_BYPASS = new HashMap<>(); private static final Map, BlockData, BlockHitResult, Boolean>> WILL_CONSUME = new HashMap<>(); private static final Map, Boolean>> ENTITY_INTERACTIONS = new HashMap<>(); + private static final Key NOTE_BLOCK_TOP_INSTRUMENTS = Key.of("minecraft:noteblock_top_instruments"); + private static final Key PARROT_POISONOUS_FOOD = Key.of("minecraft:parrot_poisonous_food"); + private static final Key HARNESSES = Key.of("minecraft:harnesses"); + private static final Key CANDLES = Key.of("minecraft:candles"); private InteractUtils() {} + // 方块 static { registerInteraction(BlockKeys.NOTE_BLOCK, (player, item, blockState, result) -> result.getDirection() != Direction.UP || !item.hasItemTag(NOTE_BLOCK_TOP_INSTRUMENTS)); - registerInteraction(BlockKeys.CAKE, (player, item, blockState, result) -> !canEat(player, false)); - registerInteraction(BlockKeys.CANDLE_CAKE, (player, item, blockState, result) -> !canEat(player, false)); - registerInteraction(BlockKeys.WHITE_CANDLE_CAKE, (player, item, blockState, result) -> !canEat(player, false)); - registerInteraction(BlockKeys.ORANGE_CANDLE_CAKE, (player, item, blockState, result) -> !canEat(player, false)); - registerInteraction(BlockKeys.MAGENTA_CANDLE_CAKE, (player, item, blockState, result) -> !canEat(player, false)); - registerInteraction(BlockKeys.LIGHT_BLUE_CANDLE_CAKE, (player, item, blockState, result) -> !canEat(player, false)); - registerInteraction(BlockKeys.YELLOW_CANDLE_CAKE, (player, item, blockState, result) -> !canEat(player, false)); - registerInteraction(BlockKeys.LIME_CANDLE_CAKE, (player, item, blockState, result) -> !canEat(player, false)); - registerInteraction(BlockKeys.PINK_CANDLE_CAKE, (player, item, blockState, result) -> !canEat(player, false)); - registerInteraction(BlockKeys.GRAY_CANDLE_CAKE, (player, item, blockState, result) -> !canEat(player, false)); - registerInteraction(BlockKeys.LIGHT_GRAY_CANDLE_CAKE, (player, item, blockState, result) -> !canEat(player, false)); - registerInteraction(BlockKeys.CYAN_CANDLE_CAKE, (player, item, blockState, result) -> !canEat(player, false)); - registerInteraction(BlockKeys.PURPLE_CANDLE_CAKE, (player, item, blockState, result) -> !canEat(player, false)); - registerInteraction(BlockKeys.BLUE_CANDLE_CAKE, (player, item, blockState, result) -> !canEat(player, false)); - registerInteraction(BlockKeys.BROWN_CANDLE_CAKE, (player, item, blockState, result) -> !canEat(player, false)); - registerInteraction(BlockKeys.GREEN_CANDLE_CAKE, (player, item, blockState, result) -> !canEat(player, false)); - registerInteraction(BlockKeys.RED_CANDLE_CAKE, (player, item, blockState, result) -> !canEat(player, false)); - registerInteraction(BlockKeys.BLACK_CANDLE_CAKE, (player, item, blockState, result) -> !canEat(player, false)); - registerInteraction(BlockKeys.COMMAND_BLOCK, (player, item, blockState, result) -> player.isOp() && player.getGameMode() == GameMode.CREATIVE); - registerInteraction(BlockKeys.CHAIN_COMMAND_BLOCK, (player, item, blockState, result) -> player.isOp() && player.getGameMode() == GameMode.CREATIVE); - registerInteraction(BlockKeys.REPEATING_COMMAND_BLOCK, (player, item, blockState, result) -> player.isOp() && player.getGameMode() == GameMode.CREATIVE); - registerInteraction(BlockKeys.JIGSAW, (player, item, blockState, result) -> player.isOp() && player.getGameMode() == GameMode.CREATIVE); - registerInteraction(BlockKeys.STRUCTURE_BLOCK, (player, item, blockState, result) -> player.isOp() && player.getGameMode() == GameMode.CREATIVE); - registerInteraction(BlockKeys.TEST_INSTANCE_BLOCK, (player, item, blockState, result) -> player.isOp() && player.getGameMode() == GameMode.CREATIVE); - registerInteraction(BlockKeys.TEST_BLOCK, (player, item, blockState, result) -> player.isOp() && player.getGameMode() == GameMode.CREATIVE); - registerInteraction(BlockKeys.LIGHT, (player, item, blockState, result) -> item.vanillaId().equals(ItemKeys.LIGHT)); - registerInteraction(BlockKeys.LODESTONE, (player, item, blockState, result) -> item.vanillaId().equals(ItemKeys.COMPASS)); - registerInteraction(BlockKeys.BEE_NEST, (player, item, blockState, result) -> { + registerInteraction(BlockKeys.POWDER_SNOW, (player, item, blockState, result) -> { Key id = item.vanillaId(); - return ItemKeys.SHEARS.equals(id) || ItemKeys.GLASS_BOTTLE.equals(id); + return ItemKeys.BUCKET.equals(id); }); - registerInteraction(BlockKeys.BEEHIVE, (player, item, blockState, result) -> { + // 自然方块 + registerInteraction(BlockKeys.OBSIDIAN, (player, item, blockState, result) -> { Key id = item.vanillaId(); - return ItemKeys.SHEARS.equals(id) || ItemKeys.GLASS_BOTTLE.equals(id); - }); - registerInteraction(BlockKeys.POWDER_SNOW, (player, item, blockState, result) -> item.vanillaId().equals(ItemKeys.BUCKET)); - registerInteraction(BlockKeys.REDSTONE_ORE, (player, item, blockState, result) -> { - Optional> behaviors = item.getItemBehavior(); - if (behaviors.isPresent()) { - for (ItemBehavior behavior : behaviors.get()) { - if (behavior instanceof BlockItemBehavior) return false; + if (ItemKeys.END_CRYSTAL.equals(id)) { + World world = player.getWorld(); + BukkitWorld bukkitWorld = new BukkitWorld(world); + BlockPos blockPos = result.getBlockPos(); + BlockPos abovePos = blockPos.relative(Direction.UP); + ExistingBlock aboveBlock = bukkitWorld.getBlockAt(abovePos); + if (!aboveBlock.id().equals(BlockKeys.AIR)) { + return false; + } else { + return true; + // TODO 需要判定区域内无任何实体 +// double x = aboveBlock.x(); +// double y = aboveBlock.y(); +// double z = aboveBlock.z(); +// Object serverWorld = bukkitWorld.serverWorld(); +// AABB aabb = new AABB(x, y, z, x + 1.0, y + 2.0, z + 1.0); +// Object nmsAABB = FastNMS.INSTANCE.constructor$AABB( +// aabb.minX, aabb.minY, aabb.minZ, +// aabb.maxX, aabb.maxY, aabb.maxZ +// ); +// boolean hasCollision = FastNMS.INSTANCE.checkEntityCollision(serverWorld, List.of(nmsAABB), x + 0.5, y + 1.0, z + 0.5); +// return !hasCollision; } } - return true; + return false; }); - registerInteraction(BlockKeys.DEEPSLATE_REDSTONE_ORE, (player, item, blockState, result) -> { - Optional> behaviors = item.getItemBehavior(); - if (behaviors.isPresent()) { - for (ItemBehavior behavior : behaviors.get()) { - if (behavior instanceof BlockItemBehavior) return false; + registerInteraction(BlockKeys.BEDROCK, (player, item, blockState, result) -> { + Key id = item.vanillaId(); + if (ItemKeys.END_CRYSTAL.equals(id)) { + World world = player.getWorld(); + BukkitWorld bukkitWorld = new BukkitWorld(world); + BlockPos blockPos = result.getBlockPos(); + BlockPos abovePos = blockPos.relative(Direction.UP); + ExistingBlock aboveBlock = bukkitWorld.getBlockAt(abovePos); + if (!aboveBlock.id().equals(BlockKeys.AIR)) { + return false; + } else { + return true; + // TODO 需要判定区域内无任何实体 +// double x = aboveBlock.x(); +// double y = aboveBlock.y(); +// double z = aboveBlock.z(); +// Object serverWorld = bukkitWorld.serverWorld(); +// AABB aabb = new AABB(x, y, z, x + 1.0, y + 2.0, z + 1.0); +// Object nmsAABB = FastNMS.INSTANCE.constructor$AABB( +// aabb.minX, aabb.minY, aabb.minZ, +// aabb.maxX, aabb.maxY, aabb.maxZ +// ); +// boolean hasCollision = FastNMS.INSTANCE.checkEntityCollision(serverWorld, List.of(nmsAABB), x + 0.5, y + 1.0, z + 0.5); +// return !hasCollision; } } - return true; + return false; + }); + // 功能方块 + registerInteraction(BlockKeys.CRAFTING_TABLE, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.STONECUTTER, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.CARTOGRAPHY_TABLE, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.SMITHING_TABLE, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.GRINDSTONE, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.LOOM, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.FURNACE, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.SMOKER, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.BLAST_FURNACE, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.CAMPFIRE, (player, item, blockState, result) -> { + if (!Config.enableRecipeSystem()) return false; + return BukkitRecipeManager.instance().recipeByInput(RecipeType.CAMPFIRE_COOKING, new SingleItemInput<>(UniqueIdItem.of(item))) != null; + }); + registerInteraction(BlockKeys.SOUL_CAMPFIRE, (player, item, blockState, result) -> { + if (!Config.enableRecipeSystem()) return false; + return BukkitRecipeManager.instance().recipeByInput(RecipeType.CAMPFIRE_COOKING, new SingleItemInput<>(UniqueIdItem.of(item))) != null; + }); + registerInteraction(BlockKeys.ANVIL, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.CHIPPED_ANVIL, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.DAMAGED_ANVIL, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.COMPOSTER, (player, item, blockState, result) -> { + if (item.getItem().getType().isCompostable()) return true; + return blockState instanceof Levelled levelled && levelled.getLevel() == levelled.getMaximumLevel(); + }); + registerInteraction(BlockKeys.JUKEBOX, (player, item, blockState, result) -> { + if (blockState instanceof Jukebox jukebox && jukebox.hasRecord()) return true; + return item.getItem().getType().isRecord(); + }); + registerInteraction(BlockKeys.ENCHANTING_TABLE, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.BREWING_STAND, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.CAULDRON, (player, item, blockState, result) -> { + Key id = item.vanillaId(); + return ItemKeys.WATER_BUCKET.equals(id) || ItemKeys.LAVA_BUCKET.equals(id); + }); + registerInteraction(BlockKeys.LAVA_CAULDRON, (player, item, blockState, result) -> { + Key id = item.vanillaId(); + return ItemKeys.BUCKET.equals(id) || ItemKeys.LAVA_BUCKET.equals(id) || ItemKeys.WATER_BUCKET.equals(id); + }); + registerInteraction(BlockKeys.WATER_CAULDRON, (player, item, blockState, result) -> { + if (blockState instanceof Levelled levelled && levelled.getLevel() == levelled.getMaximumLevel()) + return item.vanillaId().equals(ItemKeys.BUCKET); + Key id = item.vanillaId(); + return ItemKeys.GLASS_BOTTLE.equals(id) || ItemKeys.WATER_BUCKET.equals(id) || ItemKeys.LAVA_BUCKET.equals(id); }); - registerInteraction(BlockKeys.BELL, (player, item, blockState, result) -> { Direction direction = result.getDirection(); BlockPos pos = result.getBlockPos(); if (blockState instanceof Bell bell) { double y = result.getLocation().y() - pos.y(); - if (direction.axis() != Direction.Axis.Y && y <= 0.8123999834060669D) { + if (direction.axis() != Direction.Axis.Y && !(y > 0.8124F)) { Direction facing = DirectionUtils.toDirection(bell.getFacing()); Bell.Attachment attachment = bell.getAttachment(); switch (attachment) { @@ -127,276 +188,934 @@ public final class InteractUtils { } return false; }); - registerInteraction(BlockKeys.SOUL_CAMPFIRE, (player, item, blockState, result) -> { - if (!Config.enableRecipeSystem()) return false; - return BukkitRecipeManager.instance().recipeByInput(RecipeType.CAMPFIRE_COOKING, new SingleItemInput<>(UniqueIdItem.of(item))) != null; + registerInteraction(BlockKeys.BEACON, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.LODESTONE, (player, item, blockState, result) -> { + Key id = item.vanillaId(); + return ItemKeys.COMPASS.equals(id); }); - registerInteraction(BlockKeys.CAMPFIRE, (player, item, blockState, result) -> { - if (!Config.enableRecipeSystem()) return false; - return BukkitRecipeManager.instance().recipeByInput(RecipeType.CAMPFIRE_COOKING, new SingleItemInput<>(UniqueIdItem.of(item))) != null; + registerInteraction(BlockKeys.BEE_NEST, (player, item, blockState, result) -> { + if (blockState instanceof Beehive beehive && beehive.getHoneyLevel() == beehive.getMaximumHoneyLevel()) { + Key id = item.vanillaId(); + return ItemKeys.SHEARS.equals(id) || ItemKeys.GLASS_BOTTLE.equals(id); + } + return false; }); + registerInteraction(BlockKeys.BEEHIVE, (player, item, blockState, result) -> { + if (blockState instanceof Beehive beehive && beehive.getHoneyLevel() == beehive.getMaximumHoneyLevel()) { + Key id = item.vanillaId(); + return ItemKeys.SHEARS.equals(id) || ItemKeys.GLASS_BOTTLE.equals(id); + } + return false; + }); + registerInteraction(BlockKeys.FLOWER_POT, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.DECORATED_POT, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.CHISELED_BOOKSHELF, (player, item, blockState, result) -> { if (!(blockState instanceof ChiseledBookshelf chiseledBookshelf)) return false; return DirectionUtils.toDirection(chiseledBookshelf.getFacing()) == result.getDirection(); }); - registerInteraction(BlockKeys.COMPOSTER, (player, item, blockState, result) -> { - if (item.getItem().getType().isCompostable()) return true; - return blockState instanceof Levelled levelled && levelled.getLevel() == levelled.getMaximumLevel(); - }); + registerInteraction(BlockKeys.LECTERN, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.CHEST, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.BARREL, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.ENDER_CHEST, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.TRAPPED_CHEST, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.RESPAWN_ANCHOR, (player, item, blockState, result) -> { - if (item.vanillaId().equals(ItemKeys.GLOWSTONE)) return true; + Key id = item.vanillaId(); + if (ItemKeys.GLOWSTONE.equals(id)) return true; return blockState instanceof RespawnAnchor respawnAnchor && respawnAnchor.getCharges() != 0; }); - registerInteraction(BlockKeys.DECORATED_POT, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.FLOWER_POT, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.HOPPER, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.DRAGON_EGG, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.END_PORTAL_FRAME, (player, item, blockState, result) -> { + if (blockState instanceof EndPortalFrame endPortalFrame && !endPortalFrame.hasEye()) { + Key id = item.vanillaId(); + return ItemKeys.ENDER_EYE.equals(id); + } + return false; + }); + registerInteraction(BlockKeys.VAULT, (player, item, blockState, result) -> blockState instanceof Vault vault && vault.getVaultState() == Vault.State.ACTIVE); + registerInteraction(BlockKeys.SPAWNER, (player, item, blockState, result) -> { + Key id = item.vanillaId(); + return id.asString().endsWith("_spawn_egg"); + }); + registerInteraction(BlockKeys.TRIAL_SPAWNER, (player, item, blockState, result) -> { + Key id = item.vanillaId(); + return id.asString().endsWith("_spawn_egg"); + }); + // 红石方块 + registerInteraction(BlockKeys.REPEATER, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.COMPARATOR, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.LEVER, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.DAYLIGHT_DETECTOR, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.DISPENSER, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.DROPPER, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.CRAFTER, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.REPEATER, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.COMPARATOR, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.DAYLIGHT_DETECTOR, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.LECTERN, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.CHEST, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.ENDER_CHEST, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.TRAPPED_CHEST, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.BEACON, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.ENCHANTING_TABLE, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.BREWING_STAND, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.GRINDSTONE, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.ANVIL, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.CHIPPED_ANVIL, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.DAMAGED_ANVIL, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.FURNACE, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.CRAFTING_TABLE, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.CARTOGRAPHY_TABLE, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.STONECUTTER, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.SMITHING_TABLE, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.LOOM, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.BARREL, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.SMOKER, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.BLAST_FURNACE, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.LEVER, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.HOPPER, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.TNT, (player, item, blockState, result) -> { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + }); + registerInteraction(BlockKeys.REDSTONE_ORE, (player, item, blockState, result) -> { + Optional> behaviors = item.getItemBehavior(); + if (behaviors.isPresent()) { + for (ItemBehavior behavior : behaviors.get()) { + if (behavior instanceof BlockItemBehavior) return false; + } + } + return true; + }); + registerInteraction(BlockKeys.DEEPSLATE_REDSTONE_ORE, (player, item, blockState, result) -> { + Optional> behaviors = item.getItemBehavior(); + if (behaviors.isPresent()) { + for (ItemBehavior behavior : behaviors.get()) { + if (behavior instanceof BlockItemBehavior) return false; + } + } + return true; + }); + // 管理员用品 + registerInteraction(BlockKeys.COMMAND_BLOCK, (player, item, blockState, result) -> player.isOp() && player.getGameMode() == GameMode.CREATIVE); + registerInteraction(BlockKeys.CHAIN_COMMAND_BLOCK, (player, item, blockState, result) -> player.isOp() && player.getGameMode() == GameMode.CREATIVE); + registerInteraction(BlockKeys.REPEATING_COMMAND_BLOCK, (player, item, blockState, result) -> player.isOp() && player.getGameMode() == GameMode.CREATIVE); + registerInteraction(BlockKeys.JIGSAW, (player, item, blockState, result) -> player.isOp() && player.getGameMode() == GameMode.CREATIVE); + registerInteraction(BlockKeys.STRUCTURE_BLOCK, (player, item, blockState, result) -> player.isOp() && player.getGameMode() == GameMode.CREATIVE); + registerInteraction(BlockKeys.TEST_INSTANCE_BLOCK, (player, item, blockState, result) -> player.isOp() && player.getGameMode() == GameMode.CREATIVE); + registerInteraction(BlockKeys.TEST_BLOCK, (player, item, blockState, result) -> player.isOp() && player.getGameMode() == GameMode.CREATIVE); + registerInteraction(BlockKeys.LIGHT, (player, item, blockState, result) -> { + if (player.isOp() && player.getGameMode() == GameMode.CREATIVE) { + Key id = item.vanillaId(); + return ItemKeys.LIGHT.equals(id); + } + return false; + }); + // 床 + registerInteraction(BlockKeys.WHITE_BED, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.LIGHT_GRAY_BED, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.GRAY_BED, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.BLACK_BED, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.BROWN_BED, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.RED_BED, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.ORANGE_BED, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.YELLOW_BED, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.LIME_BED, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.GREEN_BED, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.CYAN_BED, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.LIGHT_BLUE_BED, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.BLUE_BED, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.PURPLE_BED, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.MAGENTA_BED, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.PINK_BED, (player, item, blockState, result) -> true); + // 蜡烛 + registerInteraction(BlockKeys.CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerInteraction(BlockKeys.WHITE_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerInteraction(BlockKeys.LIGHT_GRAY_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerInteraction(BlockKeys.GRAY_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerInteraction(BlockKeys.BLACK_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerInteraction(BlockKeys.BROWN_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerInteraction(BlockKeys.RED_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerInteraction(BlockKeys.ORANGE_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerInteraction(BlockKeys.YELLOW_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerInteraction(BlockKeys.LIME_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerInteraction(BlockKeys.GREEN_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerInteraction(BlockKeys.CYAN_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerInteraction(BlockKeys.LIGHT_BLUE_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerInteraction(BlockKeys.BLUE_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerInteraction(BlockKeys.PURPLE_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerInteraction(BlockKeys.MAGENTA_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerInteraction(BlockKeys.PINK_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + // 蛋糕 + registerInteraction(BlockKeys.CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Cake cake && cake.getBites() == 0 && item.hasItemTag(CANDLES)) return true; + return canEat(player); + }); + registerInteraction(BlockKeys.CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerInteraction(BlockKeys.WHITE_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerInteraction(BlockKeys.LIGHT_GRAY_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerInteraction(BlockKeys.GRAY_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerInteraction(BlockKeys.BLACK_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerInteraction(BlockKeys.BROWN_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerInteraction(BlockKeys.RED_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerInteraction(BlockKeys.ORANGE_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerInteraction(BlockKeys.YELLOW_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerInteraction(BlockKeys.LIME_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerInteraction(BlockKeys.GREEN_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerInteraction(BlockKeys.CYAN_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerInteraction(BlockKeys.LIGHT_BLUE_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerInteraction(BlockKeys.BLUE_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerInteraction(BlockKeys.PURPLE_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerInteraction(BlockKeys.MAGENTA_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerInteraction(BlockKeys.PINK_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + // 潜影盒 + registerInteraction(BlockKeys.SHULKER_BOX, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.WHITE_SHULKER_BOX, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.LIGHT_GRAY_SHULKER_BOX, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.GRAY_SHULKER_BOX, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.BLACK_SHULKER_BOX, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.BROWN_SHULKER_BOX, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.RED_SHULKER_BOX, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.ORANGE_SHULKER_BOX, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.YELLOW_SHULKER_BOX, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.LIME_SHULKER_BOX, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.GREEN_SHULKER_BOX, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.CYAN_SHULKER_BOX, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.LIGHT_BLUE_SHULKER_BOX, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.BLUE_SHULKER_BOX, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.PURPLE_SHULKER_BOX, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.MAGENTA_SHULKER_BOX, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.PINK_SHULKER_BOX, (player, item, blockState, result) -> true); + // 按钮 registerInteraction(BlockKeys.OAK_BUTTON, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.SPRUCE_BUTTON, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.BIRCH_BUTTON, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.JUNGLE_BUTTON, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.ACACIA_BUTTON, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.CHERRY_BUTTON, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.DARK_OAK_BUTTON, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.PALE_OAK_BUTTON, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.MANGROVE_BUTTON, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.CHERRY_BUTTON, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.PALE_OAK_BUTTON, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.BAMBOO_BUTTON, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.STONE_BUTTON, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.POLISHED_BLACKSTONE_BUTTON, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.CRIMSON_BUTTON, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.WARPED_BUTTON, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.OAK_TRAPDOOR, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.SPRUCE_TRAPDOOR, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.BIRCH_TRAPDOOR, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.JUNGLE_TRAPDOOR, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.ACACIA_TRAPDOOR, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.CHERRY_TRAPDOOR, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.DARK_OAK_TRAPDOOR, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.PALE_OAK_TRAPDOOR, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.MANGROVE_TRAPDOOR, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.BAMBOO_TRAPDOOR, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.CRIMSON_TRAPDOOR, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.WARPED_TRAPDOOR, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.STONE_BUTTON, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.POLISHED_BLACKSTONE_BUTTON, (player, item, blockState, result) -> true); + // 门 registerInteraction(BlockKeys.OAK_DOOR, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.SPRUCE_DOOR, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.BIRCH_DOOR, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.JUNGLE_DOOR, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.ACACIA_DOOR, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.CHERRY_DOOR, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.DARK_OAK_DOOR, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.PALE_OAK_DOOR, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.MANGROVE_DOOR, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.CHERRY_DOOR, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.PALE_OAK_DOOR, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.BAMBOO_DOOR, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.CRIMSON_DOOR, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.WARPED_DOOR, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.COPPER_DOOR, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.EXPOSED_COPPER_DOOR, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.OXIDIZED_COPPER_DOOR, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.WEATHERED_COPPER_DOOR, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.OXIDIZED_COPPER_DOOR, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.WAXED_COPPER_DOOR, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.WAXED_EXPOSED_COPPER_DOOR, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.WAXED_OXIDIZED_COPPER_DOOR, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.WAXED_WEATHERED_COPPER_DOOR, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.WAXED_OXIDIZED_COPPER_DOOR, (player, item, blockState, result) -> true); + // 活板门 + registerInteraction(BlockKeys.OAK_TRAPDOOR, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.SPRUCE_TRAPDOOR, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.BIRCH_TRAPDOOR, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.JUNGLE_TRAPDOOR, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.ACACIA_TRAPDOOR, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.DARK_OAK_TRAPDOOR, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.MANGROVE_TRAPDOOR, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.CHERRY_TRAPDOOR, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.PALE_OAK_TRAPDOOR, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.BAMBOO_TRAPDOOR, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.CRIMSON_TRAPDOOR, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.WARPED_TRAPDOOR, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.COPPER_TRAPDOOR, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.EXPOSED_COPPER_TRAPDOOR, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.OXIDIZED_COPPER_TRAPDOOR, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.WEATHERED_COPPER_TRAPDOOR, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.OXIDIZED_COPPER_TRAPDOOR, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.WAXED_COPPER_TRAPDOOR, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.WAXED_EXPOSED_COPPER_TRAPDOOR, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.WAXED_OXIDIZED_COPPER_TRAPDOOR, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.WAXED_WEATHERED_COPPER_TRAPDOOR, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.WAXED_OXIDIZED_COPPER_TRAPDOOR, (player, item, blockState, result) -> true); + // 栅栏门 registerInteraction(BlockKeys.OAK_FENCE_GATE, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.SPRUCE_FENCE_GATE, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.BIRCH_FENCE_GATE, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.JUNGLE_FENCE_GATE, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.ACACIA_FENCE_GATE, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.CHERRY_FENCE_GATE, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.DARK_OAK_FENCE_GATE, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.PALE_OAK_FENCE_GATE, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.MANGROVE_FENCE_GATE, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.CHERRY_FENCE_GATE, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.PALE_OAK_FENCE_GATE, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.BAMBOO_FENCE_GATE, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.CRIMSON_FENCE_GATE, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.WARPED_FENCE_GATE, (player, item, blockState, result) -> true); + // 告示牌 registerInteraction(BlockKeys.OAK_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.SPRUCE_SIGN, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.ACACIA_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.BIRCH_SIGN, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.CHERRY_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.JUNGLE_SIGN, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.ACACIA_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.DARK_OAK_SIGN, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.PALE_OAK_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.MANGROVE_SIGN, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.CHERRY_SIGN, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.PALE_OAK_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.BAMBOO_SIGN, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.WARPED_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.CRIMSON_SIGN, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.WARPED_SIGN, (player, item, blockState, result) -> true); + // 靠墙告示牌 registerInteraction(BlockKeys.OAK_WALL_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.SPRUCE_WALL_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.BIRCH_WALL_SIGN, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.ACACIA_WALL_SIGN, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.CHERRY_WALL_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.JUNGLE_WALL_SIGN, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.ACACIA_WALL_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.DARK_OAK_WALL_SIGN, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.PALE_OAK_WALL_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.MANGROVE_WALL_SIGN, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.CHERRY_WALL_SIGN, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.PALE_OAK_WALL_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.BAMBOO_WALL_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.CRIMSON_WALL_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.WARPED_WALL_SIGN, (player, item, blockState, result) -> true); + // 悬挂式告示牌 registerInteraction(BlockKeys.OAK_HANGING_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.SPRUCE_HANGING_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.BIRCH_HANGING_SIGN, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.ACACIA_HANGING_SIGN, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.CHERRY_HANGING_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.JUNGLE_HANGING_SIGN, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.ACACIA_HANGING_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.DARK_OAK_HANGING_SIGN, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.MANGROVE_HANGING_SIGN, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.CHERRY_HANGING_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.PALE_OAK_HANGING_SIGN, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.BAMBOO_HANGING_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.CRIMSON_HANGING_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.WARPED_HANGING_SIGN, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.MANGROVE_HANGING_SIGN, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.BAMBOO_HANGING_SIGN, (player, item, blockState, result) -> true); + // 靠墙悬挂式告示牌 registerInteraction(BlockKeys.OAK_WALL_HANGING_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.SPRUCE_WALL_HANGING_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.BIRCH_WALL_HANGING_SIGN, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.ACACIA_WALL_HANGING_SIGN, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.CHERRY_WALL_HANGING_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.JUNGLE_WALL_HANGING_SIGN, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.ACACIA_WALL_HANGING_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.DARK_OAK_WALL_HANGING_SIGN, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.PALE_OAK_WALL_HANGING_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.MANGROVE_WALL_HANGING_SIGN, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.CHERRY_WALL_HANGING_SIGN, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.PALE_OAK_WALL_HANGING_SIGN, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.BAMBOO_WALL_HANGING_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.CRIMSON_WALL_HANGING_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.WARPED_WALL_HANGING_SIGN, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.BAMBOO_WALL_HANGING_SIGN, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.SHULKER_BOX, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.WHITE_SHULKER_BOX, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.ORANGE_SHULKER_BOX, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.MAGENTA_SHULKER_BOX, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.LIGHT_BLUE_SHULKER_BOX, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.YELLOW_SHULKER_BOX, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.LIME_SHULKER_BOX, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.PINK_SHULKER_BOX, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.GRAY_SHULKER_BOX, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.LIGHT_GRAY_SHULKER_BOX, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.CYAN_SHULKER_BOX, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.PURPLE_SHULKER_BOX, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.BLUE_SHULKER_BOX, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.BROWN_SHULKER_BOX, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.GREEN_SHULKER_BOX, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.RED_SHULKER_BOX, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.BLACK_SHULKER_BOX, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.WHITE_BED, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.ORANGE_BED, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.MAGENTA_BED, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.LIGHT_BLUE_BED, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.YELLOW_BED, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.LIME_BED, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.PINK_BED, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.GRAY_BED, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.LIGHT_GRAY_BED, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.CYAN_BED, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.PURPLE_BED, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.BLUE_BED, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.BROWN_BED, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.GREEN_BED, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.RED_BED, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.BLACK_BED, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.DRAGON_EGG, (player, item, blockState, result) -> true); } + // 忽略潜行 static { - registerWillConsume(BlockKeys.CACTUS, (player, item, blockState, result) -> - result.getDirection() == Direction.UP && item.id().equals(ItemKeys.CACTUS)); - registerWillConsume(BlockKeys.CAULDRON, (player, item, blockState, result) -> { + registerSneakBypass(BlockKeys.LODESTONE, (player, item, blockState, result) -> { Key id = item.vanillaId(); - return ItemKeys.WATER_BUCKET.equals(id) || ItemKeys.LAVA_BUCKET.equals(id); + return ItemKeys.COMPASS.equals(id); }); - registerWillConsume(BlockKeys.LAVA_CAULDRON, (player, item, blockState, result) -> { - Key id = item.vanillaId(); - return ItemKeys.BUCKET.equals(id) || ItemKeys.LAVA_BUCKET.equals(id) || ItemKeys.WATER_BUCKET.equals(id); + registerSneakBypass(BlockKeys.END_PORTAL_FRAME, (player, item, blockState, result) -> { + if (blockState instanceof EndPortalFrame endPortalFrame && !endPortalFrame.hasEye()) { + Key id = item.vanillaId(); + return ItemKeys.ENDER_EYE.equals(id); + } + return false; }); - registerWillConsume(BlockKeys.WATER_CAULDRON, (player, item, blockState, result) -> { - if (blockState instanceof Levelled levelled && levelled.getLevel() == levelled.getMaximumLevel()) - return item.vanillaId().equals(ItemKeys.BUCKET); - Key id = item.vanillaId(); - return ItemKeys.GLASS_BOTTLE.equals(id) || ItemKeys.WATER_BUCKET.equals(id) || ItemKeys.LAVA_BUCKET.equals(id); + // 蜡烛 + registerSneakBypass(BlockKeys.CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerSneakBypass(BlockKeys.WHITE_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerSneakBypass(BlockKeys.LIGHT_GRAY_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerSneakBypass(BlockKeys.GRAY_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerSneakBypass(BlockKeys.BLACK_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerSneakBypass(BlockKeys.BROWN_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerSneakBypass(BlockKeys.RED_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerSneakBypass(BlockKeys.ORANGE_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerSneakBypass(BlockKeys.YELLOW_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerSneakBypass(BlockKeys.LIME_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerSneakBypass(BlockKeys.GREEN_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerSneakBypass(BlockKeys.CYAN_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerSneakBypass(BlockKeys.LIGHT_BLUE_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerSneakBypass(BlockKeys.BLUE_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerSneakBypass(BlockKeys.PURPLE_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerSneakBypass(BlockKeys.MAGENTA_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + registerSneakBypass(BlockKeys.PINK_CANDLE, (player, item, blockState, result) -> { + if (blockState instanceof Candle candle) { + Key id = item.vanillaId(); + if (!candle.isLit()) { + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + } + return false; + }); + // 蜡烛蛋糕 + registerSneakBypass(BlockKeys.CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerSneakBypass(BlockKeys.WHITE_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerSneakBypass(BlockKeys.LIGHT_GRAY_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerSneakBypass(BlockKeys.GRAY_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerSneakBypass(BlockKeys.BLACK_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerSneakBypass(BlockKeys.BROWN_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerSneakBypass(BlockKeys.RED_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerSneakBypass(BlockKeys.ORANGE_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerSneakBypass(BlockKeys.YELLOW_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerSneakBypass(BlockKeys.LIME_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerSneakBypass(BlockKeys.GREEN_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerSneakBypass(BlockKeys.CYAN_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerSneakBypass(BlockKeys.LIGHT_BLUE_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerSneakBypass(BlockKeys.BLUE_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerSneakBypass(BlockKeys.PURPLE_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerSneakBypass(BlockKeys.MAGENTA_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); + }); + registerSneakBypass(BlockKeys.PINK_CANDLE_CAKE, (player, item, blockState, result) -> { + if (blockState instanceof Lightable lightable && !(lightable.isLit())) { + Key id = item.vanillaId(); + return ItemKeys.FLINT_AND_STEEL.equals(id); + } + return canEat(player); }); } + // 消耗 static { - registerEntityInteraction(EntityTypeKeys.BEE, (player, entity, item) -> canFeed(entity, item)); - registerEntityInteraction(EntityTypeKeys.FOX, (player, entity, item) -> canFeed(entity, item)); - registerEntityInteraction(EntityTypeKeys.FROG, (player, entity, item) -> canFeed(entity, item)); - registerEntityInteraction(EntityTypeKeys.PANDA, (player, entity, item) -> canFeed(entity, item)); - registerEntityInteraction(EntityTypeKeys.HOGLIN, (player, entity, item) -> canFeed(entity, item)); - registerEntityInteraction(EntityTypeKeys.OCELOT, (player, entity, item) -> canFeed(entity, item)); - registerEntityInteraction(EntityTypeKeys.RABBIT, (player, entity, item) -> canFeed(entity, item)); - registerEntityInteraction(EntityTypeKeys.TURTLE, (player, entity, item) -> canFeed(entity, item)); - registerEntityInteraction(EntityTypeKeys.CHICKEN, (player, entity, item) -> canFeed(entity, item)); - registerEntityInteraction(EntityTypeKeys.SNIFFER, (player, entity, item) -> canFeed(entity, item)); - registerEntityInteraction(EntityTypeKeys.AXOLOTL, (player, entity, item) -> - canFeed(entity, item) || (item != null && item.vanillaId().equals(ItemKeys.WATER_BUCKET))); - registerEntityInteraction(EntityTypeKeys.COD, (player, entity, item) -> - item != null && item.vanillaId().equals(ItemKeys.WATER_BUCKET)); - registerEntityInteraction(EntityTypeKeys.SALMON, (player, entity, item) -> - item != null && item.vanillaId().equals(ItemKeys.WATER_BUCKET)); - registerEntityInteraction(EntityTypeKeys.TROPICAL_FISH, (player, entity, item) -> - item != null && item.vanillaId().equals(ItemKeys.WATER_BUCKET)); - registerEntityInteraction(EntityTypeKeys.PUFFERFISH, (player, entity, item) -> - item != null && item.vanillaId().equals(ItemKeys.WATER_BUCKET)); - registerEntityInteraction(EntityTypeKeys.TADPOLE, (player, entity, item) -> - item != null && item.vanillaId().equals(ItemKeys.WATER_BUCKET)); - registerEntityInteraction(EntityTypeKeys.SNOW_GOLEM, (player, entity, item) -> - shearable(entity, item)); - registerEntityInteraction(EntityTypeKeys.SHEEP, (player, entity, item) -> - canFeed(entity, item) || shearable(entity, item)); - registerEntityInteraction(EntityTypeKeys.BOGGED, (player, entity, item) -> - canFeed(entity, item) || shearable(entity, item)); - registerEntityInteraction(EntityTypeKeys.MOOSHROOM, (player, entity, item) -> - canFeed(entity, item) || shearable(entity, item) || (item != null && (item.vanillaId().equals(ItemKeys.BUCKET) || item.vanillaId().equals(ItemKeys.BOWL)))); - registerEntityInteraction(EntityTypeKeys.COW, (player, entity, item) -> - canFeed(entity, item) || (item != null && item.vanillaId().equals(ItemKeys.BUCKET))); - registerEntityInteraction(EntityTypeKeys.GOAT, (player, entity, item) -> - canFeed(entity, item) || (item != null && item.vanillaId().equals(ItemKeys.BUCKET))); - registerEntityInteraction(EntityTypeKeys.CREEPER, (player, entity, item) -> - item != null && item.vanillaId().equals(ItemKeys.FLINT_AND_STEEL)); - registerEntityInteraction(EntityTypeKeys.PIGLIN, (player, entity, item) -> - item != null && item.vanillaId().equals(ItemKeys.GOLD_INGOT)); - registerEntityInteraction(EntityTypeKeys.ARMADILLO, (player, entity, item) -> - canFeed(entity, item) || (item != null && item.vanillaId().equals(ItemKeys.BRUSH))); - registerEntityInteraction(EntityTypeKeys.ZOMBIE_HORSE, (player, entity, item) -> - entity instanceof Tameable tameable && tameable.isTamed()); - registerEntityInteraction(EntityTypeKeys.SKELETON_HORSE, (player, entity, item) -> - entity instanceof Tameable tameable && tameable.isTamed()); - registerEntityInteraction(EntityTypeKeys.PIG, (player, entity, item) -> - canFeed(entity, item) || (item != null && item.vanillaId().equals(ItemKeys.SADDLE) && !hasSaddle(player, entity)) || (hasSaddle(player, entity) && !player.isSneaking())); - registerEntityInteraction(EntityTypeKeys.STRIDER, (player, entity, item) -> - canFeed(entity, item) || (item != null && item.vanillaId().equals(ItemKeys.SADDLE) && !hasSaddle(player, entity)) || (hasSaddle(player, entity) && !player.isSneaking())); - registerEntityInteraction(EntityTypeKeys.WOLF, (player, entity, item) -> canFeed(entity, item) || isPetOwner(player, entity)); - registerEntityInteraction(EntityTypeKeys.CAT, (player, entity, item) -> canFeed(entity, item) || isPetOwner(player, entity)); + registerWillConsume(BlockKeys.CACTUS, (player, item, blockState, result) -> { + Key id = item.vanillaId(); + return result.getDirection() == Direction.UP && ItemKeys.CACTUS.equals(id); + }); + } + + // 实体 + static { + registerEntityInteraction(EntityTypeKeys.BEE, (player, entity, item) -> canBeFeed(entity, item)); + registerEntityInteraction(EntityTypeKeys.FOX, (player, entity, item) -> canBeFeed(entity, item)); + registerEntityInteraction(EntityTypeKeys.FROG, (player, entity, item) -> canBeFeed(entity, item)); + registerEntityInteraction(EntityTypeKeys.PANDA, (player, entity, item) -> canBeFeed(entity, item)); + registerEntityInteraction(EntityTypeKeys.HOGLIN, (player, entity, item) -> canBeFeed(entity, item)); + registerEntityInteraction(EntityTypeKeys.OCELOT, (player, entity, item) -> canBeFeed(entity, item)); + registerEntityInteraction(EntityTypeKeys.RABBIT, (player, entity, item) -> canBeFeed(entity, item)); + registerEntityInteraction(EntityTypeKeys.TURTLE, (player, entity, item) -> canBeFeed(entity, item)); + registerEntityInteraction(EntityTypeKeys.CHICKEN, (player, entity, item) -> canBeFeed(entity, item)); + registerEntityInteraction(EntityTypeKeys.SNIFFER, (player, entity, item) -> canBeFeed(entity, item)); + + registerEntityInteraction(EntityTypeKeys.AXOLOTL, (player, entity, item) -> { + Key id = item.vanillaId(); + return canBeFeed(entity, item) || ItemKeys.WATER_BUCKET.equals(id); + }); + registerEntityInteraction(EntityTypeKeys.COD, (player, entity, item) -> { + Key id = item.vanillaId(); + return ItemKeys.WATER_BUCKET.equals(id); + }); + registerEntityInteraction(EntityTypeKeys.SALMON, (player, entity, item) -> { + Key id = item.vanillaId(); + return ItemKeys.WATER_BUCKET.equals(id); + }); + registerEntityInteraction(EntityTypeKeys.TROPICAL_FISH, (player, entity, item) -> { + Key id = item.vanillaId(); + return ItemKeys.WATER_BUCKET.equals(id); + }); + registerEntityInteraction(EntityTypeKeys.PUFFERFISH, (player, entity, item) -> { + Key id = item.vanillaId(); + return ItemKeys.WATER_BUCKET.equals(id); + }); + registerEntityInteraction(EntityTypeKeys.TADPOLE, (player, entity, item) -> { + Key id = item.vanillaId(); + return ItemKeys.WATER_BUCKET.equals(id); + }); + + registerEntityInteraction(EntityTypeKeys.SHEEP, (player, entity, item) -> { + Key id = item.vanillaId(); + if (entity instanceof Sheep sheep && sheep.readyToBeSheared() && id.in(ItemKeys.DYES)) { + DyeColor sheepColor = sheep.getColor(); + if (sheepColor != null) { + String color = sheepColor.name().toLowerCase(); + return !Key.of(color + "_dye").equals(id); + } + } + return canBeFeed(entity, item) || canBeSheared(entity, item); + }); + registerEntityInteraction(EntityTypeKeys.MOOSHROOM, (player, entity, item) -> { + Key id = item.vanillaId(); + return canBeFeed(entity, item) || canBeSheared(entity, item) || ItemKeys.BUCKET.equals(id) || ItemKeys.BOWL.equals(id); + }); + registerEntityInteraction(EntityTypeKeys.BOGGED, (player, entity, item) -> canBeSheared(entity, item)); + registerEntityInteraction(EntityTypeKeys.SNOW_GOLEM, (player, entity, item) -> canBeSheared(entity, item)); + + registerEntityInteraction(EntityTypeKeys.COW, (player, entity, item) -> { + Key id = item.vanillaId(); + return canBeFeed(entity, item) || ItemKeys.BUCKET.equals(id); + }); + registerEntityInteraction(EntityTypeKeys.GOAT, (player, entity, item) -> { + Key id = item.vanillaId(); + return canBeFeed(entity, item) || ItemKeys.BUCKET.equals(id); + }); + registerEntityInteraction(EntityTypeKeys.CREEPER, (player, entity, item) -> { + Key id = item.vanillaId(); + return canBeFeed(entity, item) || ItemKeys.FLINT_AND_STEEL.equals(id); + }); + registerEntityInteraction(EntityTypeKeys.PIGLIN, (player, entity, item) -> { + Key id = item.vanillaId(); + return canBeFeed(entity, item) || ItemKeys.GOLD_INGOT.equals(id); + }); + registerEntityInteraction(EntityTypeKeys.ARMADILLO, (player, entity, item) -> { + Key id = item.vanillaId(); + return canBeFeed(entity, item) || ItemKeys.BRUSH.equals(id); + }); + + registerEntityInteraction(EntityTypeKeys.WOLF, (player, entity, item) -> canBeFeed(entity, item) || isPetOwner(player, entity)); + registerEntityInteraction(EntityTypeKeys.CAT, (player, entity, item) -> canBeFeed(entity, item) || isPetOwner(player, entity)); + registerEntityInteraction(EntityTypeKeys.PARROT, (player, entity, item) -> { + if (item.hasItemTag(PARROT_POISONOUS_FOOD)) return true; + return canBeFeed(entity, item) || isPetOwner(player, entity); + }); + + registerEntityInteraction(EntityTypeKeys.MINECART, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityTypeKeys.CHEST_MINECART, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.FURNACE_MINECART, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.HOPPER_MINECART, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.COMMAND_BLOCK_MINECART, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.SPAWNER_MINECART, (player, entity, item) -> { + Key id = item.vanillaId(); + return id.asString().endsWith("_spawn_egg"); + }); + registerEntityInteraction(EntityTypeKeys.BOAT, (player, entity, item) -> !player.isSneaking()); registerEntityInteraction(EntityTypeKeys.OAK_BOAT, (player, entity, item) -> !player.isSneaking()); registerEntityInteraction(EntityTypeKeys.SPRUCE_BOAT, (player, entity, item) -> !player.isSneaking()); @@ -408,31 +1127,7 @@ public final class InteractUtils { registerEntityInteraction(EntityTypeKeys.CHERRY_BOAT, (player, entity, item) -> !player.isSneaking()); registerEntityInteraction(EntityTypeKeys.PALE_OAK_BOAT, (player, entity, item) -> !player.isSneaking()); registerEntityInteraction(EntityTypeKeys.BAMBOO_RAFT, (player, entity, item) -> !player.isSneaking()); - registerEntityInteraction(EntityTypeKeys.MINECART, (player, entity, item) -> !player.isSneaking()); - registerEntityInteraction(EntityTypeKeys.PARROT, (player, entity, item) -> { - if (item != null && item.hasItemTag(Key.of("parrot_poisonous_food"))) return true; - return canFeed(entity, item) || isPetOwner(player, entity); - }); - registerEntityInteraction(EntityTypeKeys.HAPPY_GHAST, (player, entity, item) -> { - if (item != null && item.vanillaId().equals(ItemKeys.HARNESS)) return true; - if (entity instanceof HappyGhast happyGhast && !player.isSneaking()) { - ItemStack bodyItem = happyGhast.getEquipment().getItem(EquipmentSlot.BODY); - return BukkitItemManager.instance().wrap(bodyItem).hasItemTag(Key.of("harnesses")); - } - return canFeed(entity, item); - }); - registerEntityInteraction(EntityTypeKeys.ALLAY, (player, entity, item) -> true); - registerEntityInteraction(EntityTypeKeys.HORSE, (player, entity, item) -> true); - registerEntityInteraction(EntityTypeKeys.DONKEY, (player, entity, item) -> true); - registerEntityInteraction(EntityTypeKeys.MULE, (player, entity, item) -> true); - registerEntityInteraction(EntityTypeKeys.VILLAGER, (player, entity, item) -> true); - registerEntityInteraction(EntityTypeKeys.WANDERING_TRADER, (player, entity, item) -> true); - registerEntityInteraction(EntityTypeKeys.LLAMA, (player, entity, item) -> true); - registerEntityInteraction(EntityTypeKeys.TRADER_LLAMA, (player, entity, item) -> true); - registerEntityInteraction(EntityTypeKeys.CAMEL, (player, entity, item) -> true); - registerEntityInteraction(EntityTypeKeys.ITEM_FRAME, (player, entity, item) -> true); - registerEntityInteraction(EntityTypeKeys.GLOW_ITEM_FRAME, (player, entity, item) -> true); - registerEntityInteraction(EntityTypeKeys.INTERACTION, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.CHEST_BOAT, (player, entity, item) -> true); registerEntityInteraction(EntityTypeKeys.OAK_CHEST_BOAT, (player, entity, item) -> true); registerEntityInteraction(EntityTypeKeys.SPRUCE_CHEST_BOAT, (player, entity, item) -> true); @@ -444,10 +1139,100 @@ public final class InteractUtils { registerEntityInteraction(EntityTypeKeys.CHERRY_CHEST_BOAT, (player, entity, item) -> true); registerEntityInteraction(EntityTypeKeys.PALE_OAK_CHEST_BOAT, (player, entity, item) -> true); registerEntityInteraction(EntityTypeKeys.BAMBOO_CHEST_RAFT, (player, entity, item) -> true); - registerEntityInteraction(EntityTypeKeys.CHEST_MINECART, (player, entity, item) -> true); - registerEntityInteraction(EntityTypeKeys.FURNACE_MINECART, (player, entity, item) -> true); - registerEntityInteraction(EntityTypeKeys.HOPPER_MINECART, (player, entity, item) -> true); - registerEntityInteraction(EntityTypeKeys.COMMAND_BLOCK_MINECART, (player, entity, item) -> true); + + registerEntityInteraction(EntityTypeKeys.HORSE, (player, entity, item) -> { + if (!isAdult(entity)) return true; + if (entity instanceof AbstractHorse horse && isFood(entity, item)) { + if (isTamed(entity)) { + if (!isInLove(entity) && horse.isBreedItem(item.getItem())) return true; + return !isFullHealth(entity); + } + return !isFullHealth(entity) || !isFullTemper(entity); + } + return isVehicle(entity); + }); + registerEntityInteraction(EntityTypeKeys.DONKEY, (player, entity, item) -> { + if (!isAdult(entity)) return true; + if (entity instanceof AbstractHorse horse && isFood(entity, item)) { + if (isTamed(entity)) { + if (!isInLove(entity) && horse.isBreedItem(item.getItem())) return true; + return !isFullHealth(entity); + } + return !isFullHealth(entity) || !isFullTemper(entity); + } + return isVehicle(entity); + }); + registerEntityInteraction(EntityTypeKeys.MULE, (player, entity, item) -> { + if (!isAdult(entity)) return true; + if (entity instanceof AbstractHorse horse && isFood(entity, item)) { + if (isTamed(entity)) { + if (!isInLove(entity) && horse.isBreedItem(item.getItem())) return true; + return !isFullHealth(entity); + } + return !isFullHealth(entity) || !isFullTemper(entity); + } + return isVehicle(entity); + }); + registerEntityInteraction(EntityTypeKeys.LLAMA, (player, entity, item) -> { + if (!isAdult(entity)) return true; + if (entity instanceof AbstractHorse horse && isFood(entity, item)) { + if (isTamed(entity)) { + if (!isInLove(entity) && horse.isBreedItem(item.getItem())) return true; + return !isFullHealth(entity); + } + return !isFullHealth(entity) || !isFullTemper(entity); + } + return isVehicle(entity); + }); + registerEntityInteraction(EntityTypeKeys.TRADER_LLAMA, (player, entity, item) -> { + if (!isAdult(entity)) return true; + if (entity instanceof AbstractHorse horse && isFood(entity, item)) { + if (isTamed(entity)) { + if (!isInLove(entity) && horse.isBreedItem(item.getItem())) return true; + return !isFullHealth(entity); + } + return !isFullHealth(entity) || !isFullTemper(entity); + } + return isVehicle(entity); + }); + registerEntityInteraction(EntityTypeKeys.CAMEL, (player, entity, item) -> { + if (!isAdult(entity)) return true; + if (isFood(entity, item)) { + if (!isInLove(entity)) return true; + return !isFullHealth(entity); + } + return true; + }); + registerEntityInteraction(EntityTypeKeys.PIG, (player, entity, item) -> { + Key id = item.vanillaId(); + return canBeFeed(entity, item) + || (ItemKeys.SADDLE.equals(id) && !hasSaddle(player, entity) && isAdult(entity)) + || (hasSaddle(player, entity) && !player.isSneaking() && isVehicle(entity)); + }); + registerEntityInteraction(EntityTypeKeys.STRIDER, (player, entity, item) -> { + Key id = item.vanillaId(); + return canBeFeed(entity, item) + || (ItemKeys.SADDLE.equals(id) && !hasSaddle(player, entity) && isAdult(entity)) + || (hasSaddle(player, entity) && !player.isSneaking() && isVehicle(entity)); + }); + registerEntityInteraction(EntityTypeKeys.HAPPY_GHAST, (player, entity, item) -> { + if (entity instanceof HappyGhast happyGhast && isAdult(entity)) { + ItemStack bodyItem = happyGhast.getEquipment().getItem(EquipmentSlot.BODY); + boolean hasHarness = BukkitItemManager.instance().wrap(bodyItem).hasItemTag(HARNESSES); + if (item.hasItemTag(HARNESSES) && !hasHarness) return true; + return !player.isSneaking(); + } + return canBeFeed(entity, item); + }); + registerEntityInteraction(EntityTypeKeys.ZOMBIE_HORSE, (player, entity, item) -> isTamed(entity) && isVehicle(entity)); + registerEntityInteraction(EntityTypeKeys.SKELETON_HORSE, (player, entity, item) -> isTamed(entity) && isVehicle(entity)); + + registerEntityInteraction(EntityTypeKeys.ALLAY, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.VILLAGER, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.WANDERING_TRADER, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.ITEM_FRAME, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.GLOW_ITEM_FRAME, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.INTERACTION, (player, entity, item) -> true); } private static void registerInteraction(Key key, QuadFunction, BlockData, BlockHitResult, Boolean> function) { @@ -457,6 +1242,13 @@ public final class InteractUtils { } } + private static void registerSneakBypass(Key key, QuadFunction, BlockData, BlockHitResult, Boolean> function) { + var previous = SNEAK_BYPASS.put(key, function); + if (previous != null) { + CraftEngine.instance().logger().warn("Duplicated interaction check: " + key); + } + } + private static void registerWillConsume(Key key, QuadFunction, BlockData, BlockHitResult, Boolean> function) { var previous = WILL_CONSUME.put(key, function); if (previous != null) { @@ -464,7 +1256,7 @@ public final class InteractUtils { } } - private static void registerEntityInteraction(Key key, TriFunction, Boolean> function) { + private static void registerEntityInteraction(Key key, TriFunction, Boolean> function) { var previous = ENTITY_INTERACTIONS.put(key, function); if (previous != null) { CraftEngine.instance().logger().warn("Duplicated entity interaction check: " + key); @@ -475,14 +1267,16 @@ public final class InteractUtils { Key blockType = BlockStateUtils.getBlockOwnerIdFromData(state); if (INTERACTIONS.containsKey(blockType)) { return INTERACTIONS.get(blockType).apply(player, item, state, hit); - } else { - return false; } + return false; } - public static boolean isEntityInteractable(Player player, Entity entity, @Nullable Item item) { - TriFunction, Boolean> func = ENTITY_INTERACTIONS.get(EntityUtils.getEntityType(entity)); - return func != null && func.apply(player, entity, item); + public static boolean isIgnoreSneaking(Player player, BlockData state, BlockHitResult hit, @Nullable Item item) { + Key blockType = BlockStateUtils.getBlockOwnerIdFromData(state); + if (SNEAK_BYPASS.containsKey(blockType)) { + return SNEAK_BYPASS.get(blockType).apply(player, item, state, hit); + } + return false; } public static boolean willConsume(Player player, BlockData state, BlockHitResult hit, @Nullable Item item) { @@ -490,28 +1284,76 @@ public final class InteractUtils { Key blockType = BlockStateUtils.getBlockOwnerIdFromData(state); if (WILL_CONSUME.containsKey(blockType)) { return WILL_CONSUME.get(blockType).apply(player, item, state, hit); - } else { - return false; } + return false; } - private static boolean canEat(Player player, boolean ignoreHunger) { - return ignoreHunger || player.isInvulnerable() || player.getFoodLevel() < 20; + public static boolean isEntityInteractable(Player player, Entity entity, @Nullable Item item) { + TriFunction, Boolean> func = ENTITY_INTERACTIONS.get(EntityUtils.getEntityType(entity)); + return func != null && func.apply(player, entity, item); } - private static boolean canFeed(Entity entity, Item item) { - return entity instanceof Animals && item.hasItemTag(Key.of(EntityUtils.getEntityType(entity).value() + "_food")); + private static boolean canEat(Player player) { + return player.isInvulnerable() || player.getFoodLevel() < 20; } private static boolean hasSaddle(Player player, Entity entity) { return entity instanceof Steerable steerable && steerable.hasSaddle() && !player.isSneaking(); } - private static boolean shearable(Entity entity, Item item) { - return entity instanceof Shearable shearable && item.vanillaId().equals(ItemKeys.SHEARS) && shearable.readyToBeSheared(); + private static boolean isAdult(Entity entity) { + return entity instanceof Ageable ageable && ageable.isAdult(); + } + + public static boolean isFullHealth(Entity entity) { + if (entity instanceof LivingEntity living) { + Key key = AttributeModifiersModifier.getNativeAttributeName(Key.of("max_health")); + NamespacedKey maxHealthKey = KeyUtils.toNamespacedKey(key); + Attribute maxHealthAttr = Registry.ATTRIBUTE.get(maxHealthKey); + if (maxHealthAttr != null) { + AttributeInstance attribute = living.getAttribute(maxHealthAttr); + if (attribute != null) { + float health = (float) living.getHealth(); + float maxHealth = (float) attribute.getValue(); + return health >= maxHealth; + } + } + } + return false; + } + + private static boolean isFullTemper(Entity entity) { + return entity instanceof AbstractHorse horse && horse.getDomestication() == horse.getMaxDomestication(); } private static boolean isPetOwner(Player player, Entity entity) { return entity instanceof Tameable tameable && tameable.isTamed() && player.getUniqueId().equals(tameable.getOwnerUniqueId()); } + + private static boolean isTamed(Entity entity) { + return entity instanceof Tameable tameable && tameable.isTamed(); + } + + private static boolean isInLove(Entity entity) { + return entity instanceof Animals animals && animals.isLoveMode(); + } + + private static boolean isFood(Entity entity, Item item) { + return item.hasItemTag(Key.of(EntityUtils.getEntityType(entity).value() + "_food")); + } + + // 判断单座位实体是否载有乘客 + private static boolean isVehicle(Entity entity) { + return entity.isEmpty(); + } + + private static boolean canBeFeed(Entity entity, Item item) { + if (isInLove(entity)) return false; + return isFood(entity, item); + } + + private static boolean canBeSheared(Entity entity, Item item) { + Key id = item.vanillaId(); + return entity instanceof Shearable shearable && shearable.readyToBeSheared() && ItemKeys.SHEARS.equals(id); + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/BlockKeys.java b/core/src/main/java/net/momirealms/craftengine/core/block/BlockKeys.java index c6b9cd591..0382fbcbd 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/BlockKeys.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/BlockKeys.java @@ -4,41 +4,72 @@ import net.momirealms.craftengine.core.util.Key; public final class BlockKeys { private BlockKeys() {} - + // 特殊 + public static final Key AIR = Key.of("minecraft:air"); public static final Key NOTE_BLOCK = Key.of("minecraft:note_block"); public static final Key TRIPWIRE = Key.of("minecraft:tripwire"); + public static final Key CACTUS = Key.of("minecraft:cactus"); + public static final Key POWDER_SNOW = Key.of("minecraft:powder_snow"); + // 自然方块 + public static final Key OBSIDIAN = Key.of("minecraft:obsidian"); + public static final Key BEDROCK = Key.of("minecraft:bedrock"); + // 功能方块 public static final Key CRAFTING_TABLE = Key.of("minecraft:crafting_table"); - public static final Key CARTOGRAPHY_TABLE = Key.of("minecraft:cartography_table"); public static final Key STONECUTTER = Key.of("minecraft:stonecutter"); - public static final Key BELL = Key.of("minecraft:bell"); + public static final Key CARTOGRAPHY_TABLE = Key.of("minecraft:cartography_table"); public static final Key SMITHING_TABLE = Key.of("minecraft:smithing_table"); + public static final Key GRINDSTONE = Key.of("minecraft:grindstone"); public static final Key LOOM = Key.of("minecraft:loom"); - public static final Key BARREL = Key.of("minecraft:barrel"); + public static final Key FURNACE = Key.of("minecraft:furnace"); public static final Key SMOKER = Key.of("minecraft:smoker"); public static final Key BLAST_FURNACE = Key.of("minecraft:blast_furnace"); - public static final Key FURNACE = Key.of("minecraft:furnace"); - public static final Key LEVER = Key.of("minecraft:lever"); + public static final Key CAMPFIRE = Key.of("minecraft:campfire"); + public static final Key SOUL_CAMPFIRE = Key.of("minecraft:soul_campfire"); public static final Key ANVIL = Key.of("minecraft:anvil"); public static final Key CHIPPED_ANVIL = Key.of("minecraft:chipped_anvil"); public static final Key DAMAGED_ANVIL = Key.of("minecraft:damaged_anvil"); - public static final Key GRINDSTONE = Key.of("minecraft:grindstone"); + public static final Key COMPOSTER = Key.of("minecraft:composter"); + public static final Key JUKEBOX = Key.of("minecraft:jukebox"); public static final Key ENCHANTING_TABLE = Key.of("minecraft:enchanting_table"); public static final Key BREWING_STAND = Key.of("minecraft:brewing_stand"); + public static final Key CAULDRON = Key.of("minecraft:cauldron"); + public static final Key LAVA_CAULDRON = Key.of("minecraft:lava_cauldron"); + public static final Key WATER_CAULDRON = Key.of("minecraft:water_cauldron"); + public static final Key BELL = Key.of("minecraft:bell"); public static final Key BEACON = Key.of("minecraft:beacon"); + public static final Key LODESTONE = Key.of("minecraft:lodestone"); + public static final Key BEE_NEST = Key.of("minecraft:bee_nest"); + public static final Key BEEHIVE = Key.of("minecraft:beehive"); + public static final Key FLOWER_POT = Key.of("minecraft:flower_pot"); + public static final Key DECORATED_POT = Key.of("minecraft:decorated_pot"); + public static final Key CHISELED_BOOKSHELF = Key.of("minecraft:chiseled_bookshelf"); + public static final Key LECTERN = Key.of("minecraft:lectern"); + public static final Key CHEST = Key.of("minecraft:chest"); - public static final Key CAMPFIRE = Key.of("minecraft:campfire"); - public static final Key SOUL_CAMPFIRE = Key.of("minecraft:soul_campfire"); + public static final Key BARREL = Key.of("minecraft:barrel"); public static final Key ENDER_CHEST = Key.of("minecraft:ender_chest"); public static final Key TRAPPED_CHEST = Key.of("minecraft:trapped_chest"); - public static final Key DAYLIGHT_DETECTOR = Key.of("minecraft:daylight_detector"); - public static final Key LECTERN = Key.of("minecraft:lectern"); + + public static final Key RESPAWN_ANCHOR = Key.of("minecraft:respawn_anchor"); + public static final Key DRAGON_EGG = Key.of("minecraft:dragon_egg"); + public static final Key END_PORTAL_FRAME = Key.of("minecraft:end_portal_frame"); + public static final Key VAULT = Key.of("minecraft:vault"); + + public static final Key SPAWNER = Key.of("minecraft:spawner"); + public static final Key TRIAL_SPAWNER = Key.of("minecraft:trial_spawner"); + // 红石方块 public static final Key REPEATER = Key.of("minecraft:repeater"); public static final Key COMPARATOR = Key.of("minecraft:comparator"); - public static final Key DRAGON_EGG = Key.of("minecraft:dragon_egg"); - public static final Key HOPPER = Key.of("minecraft:hopper"); + public static final Key LEVER = Key.of("minecraft:lever"); + public static final Key DAYLIGHT_DETECTOR = Key.of("minecraft:daylight_detector"); public static final Key DISPENSER = Key.of("minecraft:dispenser"); public static final Key DROPPER = Key.of("minecraft:dropper"); public static final Key CRAFTER = Key.of("minecraft:crafter"); + public static final Key HOPPER = Key.of("minecraft:hopper"); + public static final Key TNT = Key.of("minecraft:tnt"); + public static final Key REDSTONE_ORE = Key.of("minecraft:redstone_ore"); + public static final Key DEEPSLATE_REDSTONE_ORE = Key.of("minecraft:deepslate_redstone_ore"); + // 管理员用品 public static final Key COMMAND_BLOCK = Key.of("minecraft:command_block"); public static final Key CHAIN_COMMAND_BLOCK = Key.of("minecraft:chain_command_block"); public static final Key REPEATING_COMMAND_BLOCK = Key.of("minecraft:repeating_command_block"); @@ -47,113 +78,103 @@ public final class BlockKeys { public static final Key TEST_INSTANCE_BLOCK = Key.of("minecraft:test_instance_block"); public static final Key TEST_BLOCK = Key.of("minecraft:test_block"); public static final Key LIGHT = Key.of("minecraft:light"); - public static final Key DECORATED_POT = Key.of("minecraft:decorated_pot"); - public static final Key FLOWER_POT = Key.of("minecraft:flower_pot"); - public static final Key CHISELED_BOOKSHELF = Key.of("minecraft:chiseled_bookshelf"); - public static final Key REDSTONE_ORE = Key.of("minecraft:redstone_ore"); - public static final Key DEEPSLATE_REDSTONE_ORE = Key.of("minecraft:deepslate_redstone_ore"); - public static final Key BEE_NEST = Key.of("minecraft:bee_nest"); - public static final Key BEEHIVE = Key.of("minecraft:beehive"); - public static final Key POWDER_SNOW = Key.of("minecraft:powder_snow"); - public static final Key COMPOSTER = Key.of("minecraft:composter"); - public static final Key CAULDRON = Key.of("minecraft:cauldron"); - public static final Key WATER_CAULDRON = Key.of("minecraft:water_cauldron"); - public static final Key LAVA_CAULDRON = Key.of("minecraft:lava_cauldron"); - public static final Key RESPAWN_ANCHOR = Key.of("minecraft:respawn_anchor"); - public static final Key LODESTONE = Key.of("minecraft:lodestone"); - + // 床 + public static final Key WHITE_BED = Key.of("minecraft:white_bed"); + public static final Key LIGHT_GRAY_BED = Key.of("minecraft:light_gray_bed"); + public static final Key GRAY_BED = Key.of("minecraft:gray_bed"); + public static final Key BLACK_BED = Key.of("minecraft:black_bed"); + public static final Key BROWN_BED = Key.of("minecraft:brown_bed"); + public static final Key RED_BED = Key.of("minecraft:red_bed"); + public static final Key ORANGE_BED = Key.of("minecraft:orange_bed"); + public static final Key YELLOW_BED = Key.of("minecraft:yellow_bed"); + public static final Key LIME_BED = Key.of("minecraft:lime_bed"); + public static final Key GREEN_BED = Key.of("minecraft:green_bed"); + public static final Key CYAN_BED = Key.of("minecraft:cyan_bed"); + public static final Key LIGHT_BLUE_BED = Key.of("minecraft:light_blue_bed"); + public static final Key BLUE_BED = Key.of("minecraft:blue_bed"); + public static final Key PURPLE_BED = Key.of("minecraft:purple_bed"); + public static final Key MAGENTA_BED = Key.of("minecraft:magenta_bed"); + public static final Key PINK_BED = Key.of("minecraft:pink_bed"); + // 蜡烛 + public static final Key CANDLE = Key.of("minecraft:candle"); + public static final Key WHITE_CANDLE = Key.of("minecraft:white_candle"); + public static final Key LIGHT_GRAY_CANDLE = Key.of("minecraft:light_gray_candle"); + public static final Key GRAY_CANDLE = Key.of("minecraft:gray_candle"); + public static final Key BLACK_CANDLE = Key.of("minecraft:black_candle"); + public static final Key BROWN_CANDLE = Key.of("minecraft:brown_candle"); + public static final Key RED_CANDLE = Key.of("minecraft:red_candle"); + public static final Key ORANGE_CANDLE = Key.of("minecraft:orange_candle"); + public static final Key YELLOW_CANDLE = Key.of("minecraft:yellow_candle"); + public static final Key LIME_CANDLE = Key.of("minecraft:lime_candle"); + public static final Key GREEN_CANDLE = Key.of("minecraft:green_candle"); + public static final Key CYAN_CANDLE = Key.of("minecraft:cyan_candle"); + public static final Key LIGHT_BLUE_CANDLE = Key.of("minecraft:light_blue_candle"); + public static final Key BLUE_CANDLE = Key.of("minecraft:blue_candle"); + public static final Key PURPLE_CANDLE = Key.of("minecraft:purple_candle"); + public static final Key MAGENTA_CANDLE = Key.of("minecraft:magenta_candle"); + public static final Key PINK_CANDLE = Key.of("minecraft:pink_candle"); + // 蛋糕 public static final Key CAKE = Key.of("minecraft:cake"); public static final Key CANDLE_CAKE = Key.of("minecraft:candle_cake"); public static final Key WHITE_CANDLE_CAKE = Key.of("minecraft:white_candle_cake"); + public static final Key LIGHT_GRAY_CANDLE_CAKE = Key.of("minecraft:light_gray_candle_cake"); + public static final Key GRAY_CANDLE_CAKE = Key.of("minecraft:gray_candle_cake"); + public static final Key BLACK_CANDLE_CAKE = Key.of("minecraft:black_candle_cake"); + public static final Key BROWN_CANDLE_CAKE = Key.of("minecraft:brown_candle_cake"); + public static final Key RED_CANDLE_CAKE = Key.of("minecraft:red_candle_cake"); public static final Key ORANGE_CANDLE_CAKE = Key.of("minecraft:orange_candle_cake"); - public static final Key MAGENTA_CANDLE_CAKE = Key.of("minecraft:magenta_candle_cake"); - public static final Key LIGHT_BLUE_CANDLE_CAKE = Key.of("minecraft:light_blue_candle_cake"); public static final Key YELLOW_CANDLE_CAKE = Key.of("minecraft:yellow_candle_cake"); public static final Key LIME_CANDLE_CAKE = Key.of("minecraft:lime_candle_cake"); - public static final Key PINK_CANDLE_CAKE = Key.of("minecraft:pink_candle_cake"); - public static final Key GRAY_CANDLE_CAKE = Key.of("minecraft:gray_candle_cake"); - public static final Key LIGHT_GRAY_CANDLE_CAKE = Key.of("minecraft:light_gray_candle_cake"); - public static final Key CYAN_CANDLE_CAKE = Key.of("minecraft:cyan_candle_cake"); - public static final Key PURPLE_CANDLE_CAKE = Key.of("minecraft:purple_candle_cake"); - public static final Key BLUE_CANDLE_CAKE = Key.of("minecraft:blue_candle_cake"); - public static final Key BROWN_CANDLE_CAKE = Key.of("minecraft:brown_candle_cake"); public static final Key GREEN_CANDLE_CAKE = Key.of("minecraft:green_candle_cake"); - public static final Key RED_CANDLE_CAKE = Key.of("minecraft:red_candle_cake"); - public static final Key BLACK_CANDLE_CAKE = Key.of("minecraft:black_candle_cake"); - - public static final Key WHITE_BED = Key.of("minecraft:white_bed"); - public static final Key ORANGE_BED = Key.of("minecraft:orange_bed"); - public static final Key MAGENTA_BED = Key.of("minecraft:magenta_bed"); - public static final Key LIGHT_BLUE_BED = Key.of("minecraft:light_blue_bed"); - public static final Key YELLOW_BED = Key.of("minecraft:yellow_bed"); - public static final Key LIME_BED = Key.of("minecraft:lime_bed"); - public static final Key PINK_BED = Key.of("minecraft:pink_bed"); - public static final Key GRAY_BED = Key.of("minecraft:gray_bed"); - public static final Key LIGHT_GRAY_BED = Key.of("minecraft:light_gray_bed"); - public static final Key CYAN_BED = Key.of("minecraft:cyan_bed"); - public static final Key PURPLE_BED = Key.of("minecraft:purple_bed"); - public static final Key BLUE_BED = Key.of("minecraft:blue_bed"); - public static final Key BROWN_BED = Key.of("minecraft:brown_bed"); - public static final Key GREEN_BED = Key.of("minecraft:green_bed"); - public static final Key RED_BED = Key.of("minecraft:red_bed"); - public static final Key BLACK_BED = Key.of("minecraft:black_bed"); - + public static final Key CYAN_CANDLE_CAKE = Key.of("minecraft:cyan_candle_cake"); + public static final Key LIGHT_BLUE_CANDLE_CAKE = Key.of("minecraft:light_blue_candle_cake"); + public static final Key BLUE_CANDLE_CAKE = Key.of("minecraft:blue_candle_cake"); + public static final Key PURPLE_CANDLE_CAKE = Key.of("minecraft:purple_candle_cake"); + public static final Key MAGENTA_CANDLE_CAKE = Key.of("minecraft:magenta_candle_cake"); + public static final Key PINK_CANDLE_CAKE = Key.of("minecraft:pink_candle_cake"); + // 潜影盒 public static final Key SHULKER_BOX = Key.of("minecraft:shulker_box"); public static final Key WHITE_SHULKER_BOX = Key.of("minecraft:white_shulker_box"); + public static final Key LIGHT_GRAY_SHULKER_BOX = Key.of("minecraft:light_gray_shulker_box"); + public static final Key GRAY_SHULKER_BOX = Key.of("minecraft:gray_shulker_box"); + public static final Key BLACK_SHULKER_BOX = Key.of("minecraft:black_shulker_box"); + public static final Key BROWN_SHULKER_BOX = Key.of("minecraft:brown_shulker_box"); + public static final Key RED_SHULKER_BOX = Key.of("minecraft:red_shulker_box"); public static final Key ORANGE_SHULKER_BOX = Key.of("minecraft:orange_shulker_box"); - public static final Key MAGENTA_SHULKER_BOX = Key.of("minecraft:magenta_shulker_box"); - public static final Key LIGHT_BLUE_SHULKER_BOX = Key.of("minecraft:light_blue_shulker_box"); public static final Key YELLOW_SHULKER_BOX = Key.of("minecraft:yellow_shulker_box"); public static final Key LIME_SHULKER_BOX = Key.of("minecraft:lime_shulker_box"); - public static final Key PINK_SHULKER_BOX = Key.of("minecraft:pink_shulker_box"); - public static final Key GRAY_SHULKER_BOX = Key.of("minecraft:gray_shulker_box"); - public static final Key LIGHT_GRAY_SHULKER_BOX = Key.of("minecraft:light_gray_shulker_box"); - public static final Key CYAN_SHULKER_BOX = Key.of("minecraft:cyan_shulker_box"); - public static final Key PURPLE_SHULKER_BOX = Key.of("minecraft:purple_shulker_box"); - public static final Key BLUE_SHULKER_BOX = Key.of("minecraft:blue_shulker_box"); - public static final Key BROWN_SHULKER_BOX = Key.of("minecraft:brown_shulker_box"); public static final Key GREEN_SHULKER_BOX = Key.of("minecraft:green_shulker_box"); - public static final Key RED_SHULKER_BOX = Key.of("minecraft:red_shulker_box"); - public static final Key BLACK_SHULKER_BOX = Key.of("minecraft:black_shulker_box"); - + public static final Key CYAN_SHULKER_BOX = Key.of("minecraft:cyan_shulker_box"); + public static final Key LIGHT_BLUE_SHULKER_BOX = Key.of("minecraft:light_blue_shulker_box"); + public static final Key BLUE_SHULKER_BOX = Key.of("minecraft:blue_shulker_box"); + public static final Key PURPLE_SHULKER_BOX = Key.of("minecraft:purple_shulker_box"); + public static final Key MAGENTA_SHULKER_BOX = Key.of("minecraft:magenta_shulker_box"); + public static final Key PINK_SHULKER_BOX = Key.of("minecraft:pink_shulker_box"); + // 按钮 public static final Key OAK_BUTTON = Key.of("minecraft:oak_button"); public static final Key SPRUCE_BUTTON = Key.of("minecraft:spruce_button"); public static final Key BIRCH_BUTTON = Key.of("minecraft:birch_button"); public static final Key JUNGLE_BUTTON = Key.of("minecraft:jungle_button"); public static final Key ACACIA_BUTTON = Key.of("minecraft:acacia_button"); - public static final Key CHERRY_BUTTON = Key.of("minecraft:cherry_button"); public static final Key DARK_OAK_BUTTON = Key.of("minecraft:dark_oak_button"); - public static final Key PALE_OAK_BUTTON = Key.of("minecraft:pale_oak_button"); public static final Key MANGROVE_BUTTON = Key.of("minecraft:mangrove_button"); + public static final Key CHERRY_BUTTON = Key.of("minecraft:cherry_button"); + public static final Key PALE_OAK_BUTTON = Key.of("minecraft:pale_oak_button"); public static final Key BAMBOO_BUTTON = Key.of("minecraft:bamboo_button"); public static final Key CRIMSON_BUTTON = Key.of("minecraft:crimson_button"); public static final Key WARPED_BUTTON = Key.of("minecraft:warped_button"); public static final Key STONE_BUTTON = Key.of("minecraft:stone_button"); public static final Key POLISHED_BLACKSTONE_BUTTON = Key.of("minecraft:polished_blackstone_button"); - - public static final Key OAK_TRAPDOOR = Key.of("minecraft:oak_trapdoor"); - public static final Key SPRUCE_TRAPDOOR = Key.of("minecraft:spruce_trapdoor"); - public static final Key BIRCH_TRAPDOOR = Key.of("minecraft:birch_trapdoor"); - public static final Key JUNGLE_TRAPDOOR = Key.of("minecraft:jungle_trapdoor"); - public static final Key ACACIA_TRAPDOOR = Key.of("minecraft:acacia_trapdoor"); - public static final Key CHERRY_TRAPDOOR = Key.of("minecraft:cherry_trapdoor"); - public static final Key DARK_OAK_TRAPDOOR = Key.of("minecraft:dark_oak_trapdoor"); - public static final Key PALE_OAK_TRAPDOOR = Key.of("minecraft:pale_oak_trapdoor"); - public static final Key MANGROVE_TRAPDOOR = Key.of("minecraft:mangrove_trapdoor"); - public static final Key BAMBOO_TRAPDOOR = Key.of("minecraft:bamboo_trapdoor"); - public static final Key CRIMSON_TRAPDOOR = Key.of("minecraft:crimson_trapdoor"); - public static final Key WARPED_TRAPDOOR = Key.of("minecraft:warped_trapdoor"); - public static final Key IRON_TRAPDOOR = Key.of("minecraft:iron_trapdoor"); - + // 门 public static final Key OAK_DOOR = Key.of("minecraft:oak_door"); public static final Key SPRUCE_DOOR = Key.of("minecraft:spruce_door"); public static final Key BIRCH_DOOR = Key.of("minecraft:birch_door"); public static final Key JUNGLE_DOOR = Key.of("minecraft:jungle_door"); public static final Key ACACIA_DOOR = Key.of("minecraft:acacia_door"); - public static final Key CHERRY_DOOR = Key.of("minecraft:cherry_door"); public static final Key DARK_OAK_DOOR = Key.of("minecraft:dark_oak_door"); - public static final Key PALE_OAK_DOOR = Key.of("minecraft:pale_oak_door"); public static final Key MANGROVE_DOOR = Key.of("minecraft:mangrove_door"); + public static final Key CHERRY_DOOR = Key.of("minecraft:cherry_door"); + public static final Key PALE_OAK_DOOR = Key.of("minecraft:pale_oak_door"); public static final Key BAMBOO_DOOR = Key.of("minecraft:bamboo_door"); public static final Key CRIMSON_DOOR = Key.of("minecraft:crimson_door"); public static final Key WARPED_DOOR = Key.of("minecraft:warped_door"); @@ -161,86 +182,98 @@ public final class BlockKeys { public static final Key COPPER_DOOR = Key.of("minecraft:copper_door"); public static final Key EXPOSED_COPPER_DOOR = Key.of("minecraft:exposed_copper_door"); - public static final Key OXIDIZED_COPPER_DOOR = Key.of("minecraft:oxidized_copper_door"); public static final Key WEATHERED_COPPER_DOOR = Key.of("minecraft:weathered_copper_door"); + public static final Key OXIDIZED_COPPER_DOOR = Key.of("minecraft:oxidized_copper_door"); public static final Key WAXED_COPPER_DOOR = Key.of("minecraft:waxed_copper_door"); public static final Key WAXED_EXPOSED_COPPER_DOOR = Key.of("minecraft:waxed_exposed_copper_door"); - public static final Key WAXED_OXIDIZED_COPPER_DOOR = Key.of("minecraft:waxed_oxidized_copper_door"); public static final Key WAXED_WEATHERED_COPPER_DOOR = Key.of("minecraft:waxed_weathered_copper_door"); + public static final Key WAXED_OXIDIZED_COPPER_DOOR = Key.of("minecraft:waxed_oxidized_copper_door"); + // 活板门 + public static final Key OAK_TRAPDOOR = Key.of("minecraft:oak_trapdoor"); + public static final Key SPRUCE_TRAPDOOR = Key.of("minecraft:spruce_trapdoor"); + public static final Key BIRCH_TRAPDOOR = Key.of("minecraft:birch_trapdoor"); + public static final Key JUNGLE_TRAPDOOR = Key.of("minecraft:jungle_trapdoor"); + public static final Key ACACIA_TRAPDOOR = Key.of("minecraft:acacia_trapdoor"); + public static final Key DARK_OAK_TRAPDOOR = Key.of("minecraft:dark_oak_trapdoor"); + public static final Key MANGROVE_TRAPDOOR = Key.of("minecraft:mangrove_trapdoor"); + public static final Key CHERRY_TRAPDOOR = Key.of("minecraft:cherry_trapdoor"); + public static final Key PALE_OAK_TRAPDOOR = Key.of("minecraft:pale_oak_trapdoor"); + public static final Key BAMBOO_TRAPDOOR = Key.of("minecraft:bamboo_trapdoor"); + public static final Key CRIMSON_TRAPDOOR = Key.of("minecraft:crimson_trapdoor"); + public static final Key WARPED_TRAPDOOR = Key.of("minecraft:warped_trapdoor"); + public static final Key IRON_TRAPDOOR = Key.of("minecraft:iron_trapdoor"); public static final Key COPPER_TRAPDOOR = Key.of("minecraft:copper_trapdoor"); public static final Key EXPOSED_COPPER_TRAPDOOR = Key.of("minecraft:exposed_copper_trapdoor"); - public static final Key OXIDIZED_COPPER_TRAPDOOR = Key.of("minecraft:oxidized_copper_trapdoor"); public static final Key WEATHERED_COPPER_TRAPDOOR = Key.of("minecraft:weathered_copper_trapdoor"); + public static final Key OXIDIZED_COPPER_TRAPDOOR = Key.of("minecraft:oxidized_copper_trapdoor"); public static final Key WAXED_COPPER_TRAPDOOR = Key.of("minecraft:waxed_copper_trapdoor"); public static final Key WAXED_EXPOSED_COPPER_TRAPDOOR = Key.of("minecraft:waxed_exposed_copper_trapdoor"); - public static final Key WAXED_OXIDIZED_COPPER_TRAPDOOR = Key.of("minecraft:waxed_oxidized_copper_trapdoor"); public static final Key WAXED_WEATHERED_COPPER_TRAPDOOR = Key.of("minecraft:waxed_weathered_copper_trapdoor"); - + public static final Key WAXED_OXIDIZED_COPPER_TRAPDOOR = Key.of("minecraft:waxed_oxidized_copper_trapdoor"); + // 栅栏门 public static final Key OAK_FENCE_GATE = Key.of("minecraft:oak_fence_gate"); public static final Key SPRUCE_FENCE_GATE = Key.of("minecraft:spruce_fence_gate"); public static final Key BIRCH_FENCE_GATE = Key.of("minecraft:birch_fence_gate"); public static final Key JUNGLE_FENCE_GATE = Key.of("minecraft:jungle_fence_gate"); public static final Key ACACIA_FENCE_GATE = Key.of("minecraft:acacia_fence_gate"); - public static final Key CHERRY_FENCE_GATE = Key.of("minecraft:cherry_fence_gate"); public static final Key DARK_OAK_FENCE_GATE = Key.of("minecraft:dark_oak_fence_gate"); - public static final Key PALE_OAK_FENCE_GATE = Key.of("minecraft:pale_oak_fence_gate"); public static final Key MANGROVE_FENCE_GATE = Key.of("minecraft:mangrove_fence_gate"); + public static final Key CHERRY_FENCE_GATE = Key.of("minecraft:cherry_fence_gate"); + public static final Key PALE_OAK_FENCE_GATE = Key.of("minecraft:pale_oak_fence_gate"); public static final Key BAMBOO_FENCE_GATE = Key.of("minecraft:bamboo_fence_gate"); public static final Key CRIMSON_FENCE_GATE = Key.of("minecraft:crimson_fence_gate"); public static final Key WARPED_FENCE_GATE = Key.of("minecraft:warped_fence_gate"); - + // 告示牌 public static final Key OAK_SIGN = Key.of("minecraft:oak_sign"); public static final Key SPRUCE_SIGN = Key.of("minecraft:spruce_sign"); - public static final Key ACACIA_SIGN = Key.of("minecraft:acacia_sign"); public static final Key BIRCH_SIGN = Key.of("minecraft:birch_sign"); - public static final Key CHERRY_SIGN = Key.of("minecraft:cherry_sign"); public static final Key JUNGLE_SIGN = Key.of("minecraft:jungle_sign"); + public static final Key ACACIA_SIGN = Key.of("minecraft:acacia_sign"); public static final Key DARK_OAK_SIGN = Key.of("minecraft:dark_oak_sign"); - public static final Key PALE_OAK_SIGN = Key.of("minecraft:pale_oak_sign"); public static final Key MANGROVE_SIGN = Key.of("minecraft:mangrove_sign"); + public static final Key CHERRY_SIGN = Key.of("minecraft:cherry_sign"); + public static final Key PALE_OAK_SIGN = Key.of("minecraft:pale_oak_sign"); public static final Key BAMBOO_SIGN = Key.of("minecraft:bamboo_sign"); - public static final Key WARPED_SIGN = Key.of("minecraft:warped_sign"); public static final Key CRIMSON_SIGN = Key.of("minecraft:crimson_sign"); - + public static final Key WARPED_SIGN = Key.of("minecraft:warped_sign"); + // 靠墙告示牌 public static final Key OAK_WALL_SIGN = Key.of("minecraft:oak_wall_sign"); public static final Key SPRUCE_WALL_SIGN = Key.of("minecraft:spruce_wall_sign"); public static final Key BIRCH_WALL_SIGN = Key.of("minecraft:birch_wall_sign"); - public static final Key ACACIA_WALL_SIGN = Key.of("minecraft:acacia_wall_sign"); - public static final Key CHERRY_WALL_SIGN = Key.of("minecraft:cherry_wall_sign"); public static final Key JUNGLE_WALL_SIGN = Key.of("minecraft:jungle_wall_sign"); + public static final Key ACACIA_WALL_SIGN = Key.of("minecraft:acacia_wall_sign"); public static final Key DARK_OAK_WALL_SIGN = Key.of("minecraft:dark_oak_wall_sign"); - public static final Key PALE_OAK_WALL_SIGN = Key.of("minecraft:pale_oak_wall_sign"); public static final Key MANGROVE_WALL_SIGN = Key.of("minecraft:mangrove_wall_sign"); + public static final Key CHERRY_WALL_SIGN = Key.of("minecraft:cherry_wall_sign"); + public static final Key PALE_OAK_WALL_SIGN = Key.of("minecraft:pale_oak_wall_sign"); public static final Key BAMBOO_WALL_SIGN = Key.of("minecraft:bamboo_wall_sign"); public static final Key CRIMSON_WALL_SIGN = Key.of("minecraft:crimson_wall_sign"); public static final Key WARPED_WALL_SIGN = Key.of("minecraft:warped_wall_sign"); - + // 悬挂式告示牌 public static final Key OAK_HANGING_SIGN = Key.of("minecraft:oak_hanging_sign"); public static final Key SPRUCE_HANGING_SIGN = Key.of("minecraft:spruce_hanging_sign"); public static final Key BIRCH_HANGING_SIGN = Key.of("minecraft:birch_hanging_sign"); - public static final Key ACACIA_HANGING_SIGN = Key.of("minecraft:acacia_hanging_sign"); - public static final Key CHERRY_HANGING_SIGN = Key.of("minecraft:cherry_hanging_sign"); public static final Key JUNGLE_HANGING_SIGN = Key.of("minecraft:jungle_hanging_sign"); + public static final Key ACACIA_HANGING_SIGN = Key.of("minecraft:acacia_hanging_sign"); public static final Key DARK_OAK_HANGING_SIGN = Key.of("minecraft:dark_oak_hanging_sign"); + public static final Key MANGROVE_HANGING_SIGN = Key.of("minecraft:mangrove_hanging_sign"); + public static final Key CHERRY_HANGING_SIGN = Key.of("minecraft:cherry_hanging_sign"); public static final Key PALE_OAK_HANGING_SIGN = Key.of("minecraft:pale_oak_hanging_sign"); + public static final Key BAMBOO_HANGING_SIGN = Key.of("minecraft:bamboo_hanging_sign"); public static final Key CRIMSON_HANGING_SIGN = Key.of("minecraft:crimson_hanging_sign"); public static final Key WARPED_HANGING_SIGN = Key.of("minecraft:warped_hanging_sign"); - public static final Key MANGROVE_HANGING_SIGN = Key.of("minecraft:mangrove_hanging_sign"); - public static final Key BAMBOO_HANGING_SIGN = Key.of("minecraft:bamboo_hanging_sign"); - + // 靠墙悬挂式告示牌 public static final Key OAK_WALL_HANGING_SIGN = Key.of("minecraft:oak_wall_hanging_sign"); public static final Key SPRUCE_WALL_HANGING_SIGN = Key.of("minecraft:spruce_wall_hanging_sign"); public static final Key BIRCH_WALL_HANGING_SIGN = Key.of("minecraft:birch_wall_hanging_sign"); - public static final Key ACACIA_WALL_HANGING_SIGN = Key.of("minecraft:acacia_wall_hanging_sign"); - public static final Key CHERRY_WALL_HANGING_SIGN = Key.of("minecraft:cherry_wall_hanging_sign"); public static final Key JUNGLE_WALL_HANGING_SIGN = Key.of("minecraft:jungle_wall_hanging_sign"); + public static final Key ACACIA_WALL_HANGING_SIGN = Key.of("minecraft:acacia_wall_hanging_sign"); public static final Key DARK_OAK_WALL_HANGING_SIGN = Key.of("minecraft:dark_oak_wall_hanging_sign"); - public static final Key PALE_OAK_WALL_HANGING_SIGN = Key.of("minecraft:pale_oak_wall_hanging_sign"); public static final Key MANGROVE_WALL_HANGING_SIGN = Key.of("minecraft:mangrove_wall_hanging_sign"); + public static final Key CHERRY_WALL_HANGING_SIGN = Key.of("minecraft:cherry_wall_hanging_sign"); + public static final Key PALE_OAK_WALL_HANGING_SIGN = Key.of("minecraft:pale_oak_wall_hanging_sign"); + public static final Key BAMBOO_WALL_HANGING_SIGN = Key.of("minecraft:bamboo_wall_hanging_sign"); public static final Key CRIMSON_WALL_HANGING_SIGN = Key.of("minecraft:crimson_wall_hanging_sign"); public static final Key WARPED_WALL_HANGING_SIGN = Key.of("minecraft:warped_wall_hanging_sign"); - public static final Key BAMBOO_WALL_HANGING_SIGN = Key.of("minecraft:bamboo_wall_hanging_sign"); - - public static final Key CACTUS = Key.of("minecraft:cactus"); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/EntityTypeKeys.java b/core/src/main/java/net/momirealms/craftengine/core/entity/EntityTypeKeys.java index c4829722a..eb673d169 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/EntityTypeKeys.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/EntityTypeKeys.java @@ -81,4 +81,5 @@ public class EntityTypeKeys { public static final Key FURNACE_MINECART = Key.of("minecraft:furnace_minecart"); public static final Key HOPPER_MINECART = Key.of("minecraft:hopper_minecart"); public static final Key COMMAND_BLOCK_MINECART = Key.of("minecraft:command_block_minecart"); + public static final Key SPAWNER_MINECART = Key.of("minecraft:spawner_minecart"); } \ No newline at end of file diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ItemKeys.java b/core/src/main/java/net/momirealms/craftengine/core/item/ItemKeys.java index cf0c172e5..c129fe832 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ItemKeys.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ItemKeys.java @@ -43,24 +43,26 @@ public final class ItemKeys { public static final Key LIGHT = Key.of("minecraft:light"); public static final Key GLOWSTONE = Key.of("minecraft:glowstone"); public static final Key SADDLE = Key.of("minecraft:saddle"); - public static final Key HARNESS = Key.of("minecraft:harness"); + public static final Key FIREWORK_STAR = Key.of("minecraft:firework_star"); + public static final Key ENDER_EYE = Key.of("minecraft:ender_eye"); + public static final Key END_CRYSTAL = Key.of("minecraft:end_crystal"); + public static final Key WHITE_DYE = Key.of("minecraft:white_dye"); + public static final Key LIGHT_GRAY_DYE = Key.of("minecraft:light_gray_dye"); + public static final Key GRAY_DYE = Key.of("minecraft:gray_dye"); + public static final Key BLACK_DYE = Key.of("minecraft:black_dye"); + public static final Key BROWN_DYE = Key.of("minecraft:brown_dye"); + public static final Key RED_DYE = Key.of("minecraft:red_dye"); public static final Key ORANGE_DYE = Key.of("minecraft:orange_dye"); - public static final Key MAGENTA_DYE = Key.of("minecraft:magenta_dye"); - public static final Key LIGHT_BLUE_DYE = Key.of("minecraft:light_blue_dye"); public static final Key YELLOW_DYE = Key.of("minecraft:yellow_dye"); public static final Key LIME_DYE = Key.of("minecraft:lime_dye"); - public static final Key PINK_DYE = Key.of("minecraft:pink_dye"); - public static final Key GRAY_DYE = Key.of("minecraft:gray_dye"); - public static final Key LIGHT_GRAY_DYE = Key.of("minecraft:light_gray_dye"); - public static final Key CYAN_DYE = Key.of("minecraft:cyan_dye"); - public static final Key PURPLE_DYE = Key.of("minecraft:purple_dye"); - public static final Key BLUE_DYE = Key.of("minecraft:blue_dye"); - public static final Key BROWN_DYE = Key.of("minecraft:brown_dye"); public static final Key GREEN_DYE = Key.of("minecraft:green_dye"); - public static final Key RED_DYE = Key.of("minecraft:red_dye"); - public static final Key BLACK_DYE = Key.of("minecraft:black_dye"); - public static final Key FIREWORK_STAR = Key.of("minecraft:firework_star"); + public static final Key CYAN_DYE = Key.of("minecraft:cyan_dye"); + public static final Key LIGHT_BLUE_DYE = Key.of("minecraft:light_blue_dye"); + public static final Key BLUE_DYE = Key.of("minecraft:blue_dye"); + public static final Key PURPLE_DYE = Key.of("minecraft:purple_dye"); + public static final Key MAGENTA_DYE = Key.of("minecraft:magenta_dye"); + public static final Key PINK_DYE = Key.of("minecraft:pink_dye"); public static final Key[] AXES = new Key[] { WOODEN_AXE, STONE_AXE, IRON_AXE, GOLDEN_AXE, DIAMOND_AXE, NETHERITE_AXE @@ -69,4 +71,9 @@ public final class ItemKeys { public static final Key[] WATER_BUCKETS = new Key[] { WATER_BUCKET, COD_BUCKET, SALMON_BUCKET, TROPICAL_FISH_BUCKET, TADPOLE_BUCKET, PUFFERFISH_BUCKET, AXOLOTL_BUCKET }; + + public static final Key[] DYES = new Key[] { + WHITE_DYE, LIGHT_GRAY_DYE, GRAY_DYE, BLACK_DYE, BROWN_DYE, RED_DYE, ORANGE_DYE, YELLOW_DYE, LIME_DYE, + GREEN_DYE, CYAN_DYE, LIGHT_BLUE_DYE, BLUE_DYE, PURPLE_DYE, MAGENTA_DYE, PINK_DYE + }; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/Key.java b/core/src/main/java/net/momirealms/craftengine/core/util/Key.java index 16594275a..6d9e96b95 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/Key.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/Key.java @@ -57,6 +57,21 @@ public record Key(String namespace, String value) { return this.value.equals(key.value()) && this.namespace.equals(key.namespace()); } + public boolean in(Key... items) { + if (items == null) { + return false; + } + for (Key key : items) { + if (key == this) { + return true; + } + if (this.value.equals(key.value()) && this.namespace.equals(key.namespace())) { + return true; + } + } + return false; + } + @Override public @NotNull String toString() { return asString();