From 2d9370615e7c6b1b782b341d75110cc8ae61ae86 Mon Sep 17 00:00:00 2001 From: halogly Date: Wed, 16 Jul 2025 18:22:07 +0800 Subject: [PATCH 01/16] Improve entity and block interaction handling Added checks for interactable entities and blocks, including chiseled bookshelf, redstone ore, and deepslate redstone ore. Updated ItemEventListener to use new InteractUtils methods for entity and block interactions, preventing custom item execution on interactable entities and blocks. --- .../item/listener/ItemEventListener.java | 33 ++++++++------ .../bukkit/util/InteractUtils.java | 44 ++++++++++++++++++- .../craftengine/core/block/BlockKeys.java | 3 ++ 3 files changed, 66 insertions(+), 14 deletions(-) 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 b10dd7ad7..b507b3b6f 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 @@ -36,6 +36,7 @@ import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Openable; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -66,6 +67,8 @@ public class ItemEventListener implements Listener { @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) public void onInteractEntity(PlayerInteractEntityEvent event) { + Player player = event.getPlayer(); + Entity entity = event.getRightClicked(); BukkitServerPlayer serverPlayer = this.plugin.adapt(event.getPlayer()); if (serverPlayer == null) return; InteractionHand hand = event.getHand() == EquipmentSlot.HAND ? InteractionHand.MAIN_HAND : InteractionHand.OFF_HAND; @@ -75,15 +78,17 @@ public class ItemEventListener implements Listener { Optional> optionalCustomItem = itemInHand.getCustomItem(); if (optionalCustomItem.isEmpty()) return; - Cancellable cancellable = Cancellable.of(event::isCancelled, event::setCancelled); - PlayerOptionalContext context = PlayerOptionalContext.of(serverPlayer, ContextHolder.builder() - .withOptionalParameter(DirectContextParameters.ITEM_IN_HAND, itemInHand) - .withParameter(DirectContextParameters.EVENT, cancellable) - .withParameter(DirectContextParameters.POSITION, LocationUtils.toWorldPosition(event.getRightClicked().getLocation())) - .withParameter(DirectContextParameters.HAND, hand) - ); - CustomItem customItem = optionalCustomItem.get(); - customItem.execute(context, EventTrigger.RIGHT_CLICK); + if (!InteractUtils.isEntityInteractable(player, entity, itemInHand)) { + Cancellable cancellable = Cancellable.of(event::isCancelled, event::setCancelled); + PlayerOptionalContext context = PlayerOptionalContext.of(serverPlayer, ContextHolder.builder() + .withOptionalParameter(DirectContextParameters.ITEM_IN_HAND, itemInHand) + .withParameter(DirectContextParameters.EVENT, cancellable) + .withParameter(DirectContextParameters.POSITION, LocationUtils.toWorldPosition(event.getRightClicked().getLocation())) + .withParameter(DirectContextParameters.HAND, hand) + ); + CustomItem customItem = optionalCustomItem.get(); + customItem.execute(context, EventTrigger.RIGHT_CLICK); + } } @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) @@ -275,10 +280,12 @@ public class ItemEventListener implements Listener { .withParameter(DirectContextParameters.EVENT, dummy) ); CustomItem customItem = optionalCustomItem.get(); - customItem.execute(context, EventTrigger.RIGHT_CLICK); - if (dummy.isCancelled()) { - event.setCancelled(true); - return; + if (!InteractUtils.isInteractable(player, blockData, hitResult, null)) { + customItem.execute(context, EventTrigger.RIGHT_CLICK); + if (dummy.isCancelled()) { + event.setCancelled(true); + return; + } } } 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 11f5213b8..281b1ed0f 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 @@ -16,12 +16,14 @@ import net.momirealms.craftengine.core.world.BlockHitResult; import net.momirealms.craftengine.core.world.BlockPos; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.type.Bell; -import org.bukkit.entity.Player; +import org.bukkit.entity.*; +import org.bukkit.entity.minecart.RideableMinecart; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Nullable; import java.util.HashMap; import java.util.Map; +import java.util.Set; public class InteractUtils { private static final Map, BlockData, BlockHitResult, Boolean>> INTERACTIONS = new HashMap<>(); @@ -88,6 +90,7 @@ public class InteractUtils { item.recipeIngredientId(), item ))) != null; }); + registerInteraction(BlockKeys.CHISELED_BOOKSHELF, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.DECORATED_POT, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.HOPPER, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.DISPENSER, (player, item, blockState, result) -> true); @@ -267,6 +270,8 @@ public class InteractUtils { registerInteraction(BlockKeys.REPEATING_COMMAND_BLOCK, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.CHAIN_COMMAND_BLOCK, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.COMMAND_BLOCK, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.REDSTONE_ORE, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.DEEPSLATE_REDSTONE_ORE, (player, item, blockState, result) -> true); } static { @@ -274,6 +279,27 @@ public class InteractUtils { result.getDirection() == Direction.UP && item.id().equals(ItemKeys.CACTUS)); } + private static final Set INTERACTABLE_ENTITIES = Set.of( + EntityType.ALLAY, + EntityType.HORSE, + EntityType.ZOMBIE_HORSE, + EntityType.SKELETON_HORSE, + EntityType.DONKEY, + EntityType.MULE, + EntityType.VILLAGER, + EntityType.WANDERING_TRADER, + EntityType.LLAMA, + EntityType.TRADER_LLAMA, + EntityType.CAMEL, + EntityType.CHEST_MINECART, + EntityType.FURNACE_MINECART, + EntityType.HOPPER_MINECART, + EntityType.COMMAND_BLOCK_MINECART, + EntityType.ITEM_FRAME, + EntityType.GLOW_ITEM_FRAME, + EntityType.HAPPY_GHAST + ); + private static void registerInteraction(Key key, QuadFunction, BlockData, BlockHitResult, Boolean> function) { var previous = INTERACTIONS.put(key, function); if (previous != null) { @@ -297,6 +323,22 @@ public class InteractUtils { } } + public static boolean isEntityInteractable(Player player, Entity entity, Item item) { + boolean isSneaking = player.isSneaking(); + if (entity.getType() == EntityType.PIGLIN && + item != null && + item.vanillaId().equals(Key.of("minecraft:gold_ingot"))) { + return true; + } + return switch (entity) { + case ChestBoat ignored -> true; + case Boat ignored -> !isSneaking; + case RideableMinecart ignored -> !isSneaking; + case Steerable steerable -> !isSneaking && steerable.hasSaddle(); + default -> INTERACTABLE_ENTITIES.contains(entity.getType()); + }; + } + public static boolean willConsume(Player player, BlockData state, BlockHitResult hit, @Nullable Item item) { if (item == null) return false; Key blockType = BlockStateUtils.getBlockOwnerIdFromData(state); 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 fba210d01..4e377f7d2 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 @@ -42,6 +42,9 @@ public final class BlockKeys { 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"); 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 REDSTONE_ORE = Key.of("minecraft:redstone_ore"); + public static final Key DEEPSLATE_REDSTONE_ORE = Key.of("minecraft:deepslate_redstone_ore"); public static final Key CAKE = Key.of("minecraft:cake"); public static final Key CANDLE_CAKE = Key.of("minecraft:candle_cake"); From 348f004500e910c231d3d21a4b8e3fc132a62d1b Mon Sep 17 00:00:00 2001 From: halogly Date: Fri, 18 Jul 2025 13:42:49 +0800 Subject: [PATCH 02/16] Add support for Happy Ghast and harness interactions Introduces logic for handling Happy Ghast entity interactions and harness item tags, gated by Minecraft version 1.21.6. Refactors entity and block interaction checks to use new utility methods and dynamic entity sets, improving maintainability and future compatibility. --- .../item/listener/ItemEventListener.java | 17 ++++---- .../craftengine/bukkit/util/EntityUtils.java | 29 +++++++++++-- .../bukkit/util/InteractUtils.java | 43 ++++++++++++++----- .../craftengine/bukkit/util/ItemTags.java | 15 +++++++ 4 files changed, 81 insertions(+), 23 deletions(-) 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 b507b3b6f..8f2095acf 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 @@ -34,6 +34,8 @@ import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.block.ChiseledBookshelf; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Openable; import org.bukkit.entity.Entity; @@ -53,10 +55,7 @@ import org.bukkit.inventory.EnchantingInventory; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.Optional; +import java.util.*; public class ItemEventListener implements Listener { private final BukkitCraftEngine plugin; @@ -280,12 +279,12 @@ public class ItemEventListener implements Listener { .withParameter(DirectContextParameters.EVENT, dummy) ); CustomItem customItem = optionalCustomItem.get(); - if (!InteractUtils.isInteractable(player, blockData, hitResult, null)) { + if (!InteractUtils.isInteractable(player, blockData, hitResult, itemInHand) && !player.isSneaking()) { customItem.execute(context, EventTrigger.RIGHT_CLICK); - if (dummy.isCancelled()) { - event.setCancelled(true); - return; - } + } + if (dummy.isCancelled()) { + event.setCancelled(true); + return; } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java index 30fd6fa4b..0dfe4ec0d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java @@ -2,14 +2,17 @@ package net.momirealms.craftengine.bukkit.util; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; +import net.momirealms.craftengine.core.item.Item; +import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.world.BlockPos; import org.bukkit.Location; import org.bukkit.World; -import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Player; +import org.bukkit.entity.*; import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.inventory.EntityEquipment; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; import java.util.function.Consumer; @@ -34,4 +37,24 @@ public class EntityUtils { return LegacyEntityUtils.spawnEntity(world, loc, type, function); } } + + public static boolean isPiglinWithGoldIngot(Entity entity, Item item) { + return entity.getType() == EntityType.PIGLIN && + item != null && + item.vanillaId().equals(Key.of("minecraft:gold_ingot")); + } + + public static boolean isHappyGhastRideable(Entity entity) { + if (!VersionHelper.isOrAbove1_21_6() && + !entity.getType().name().equals("HAPPY_GHAST")) return false; + return entity instanceof LivingEntity livingEntity + && livingEntity.getEquipment() != null + && hasHarness(livingEntity.getEquipment()); + } + + public static boolean hasHarness(EntityEquipment equipment) { + ItemStack bodyItem = equipment.getItem(EquipmentSlot.BODY); + return ItemTags.ITEMS_HARNESSES != null && + ItemTags.ITEMS_HARNESSES.isTagged(bodyItem.getType()); + } } 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 281b1ed0f..54e1aba40 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 @@ -12,23 +12,25 @@ import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.util.Direction; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.QuadFunction; +import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.world.BlockHitResult; import net.momirealms.craftengine.core.world.BlockPos; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.type.Bell; +import org.bukkit.block.data.type.ChiseledBookshelf; import org.bukkit.entity.*; import org.bukkit.entity.minecart.RideableMinecart; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Nullable; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; +import java.lang.reflect.Field; +import java.util.*; public class InteractUtils { private static final Map, BlockData, BlockHitResult, Boolean>> INTERACTIONS = new HashMap<>(); private static final Map, BlockData, BlockHitResult, Boolean>> WILL_CONSUME = new HashMap<>(); private static final Key NOTE_BLOCK_TOP_INSTRUMENTS = Key.of("minecraft:noteblock_top_instruments"); + private static final Set INTERACTABLE_ENTITIES = createInteractableEntities(); private InteractUtils() {} @@ -90,7 +92,15 @@ public class InteractUtils { item.recipeIngredientId(), item ))) != null; }); - registerInteraction(BlockKeys.CHISELED_BOOKSHELF, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.CHISELED_BOOKSHELF, (player, item, blockState, result) -> { + Direction direction = result.getDirection(); + if (player.isSneaking()) return false; + if (blockState instanceof ChiseledBookshelf chiseledBookshelf) { + Direction facing = DirectionUtils.toDirection(chiseledBookshelf.getFacing()); + return facing == direction; + } + return false; + }); registerInteraction(BlockKeys.DECORATED_POT, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.HOPPER, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.DISPENSER, (player, item, blockState, result) -> true); @@ -279,7 +289,9 @@ public class InteractUtils { result.getDirection() == Direction.UP && item.id().equals(ItemKeys.CACTUS)); } - private static final Set INTERACTABLE_ENTITIES = Set.of( + private static Set createInteractableEntities() { + Set set = EnumSet.noneOf(EntityType.class); + set.addAll(Set.of( EntityType.ALLAY, EntityType.HORSE, EntityType.ZOMBIE_HORSE, @@ -296,9 +308,17 @@ public class InteractUtils { EntityType.HOPPER_MINECART, EntityType.COMMAND_BLOCK_MINECART, EntityType.ITEM_FRAME, - EntityType.GLOW_ITEM_FRAME, - EntityType.HAPPY_GHAST - ); + EntityType.GLOW_ITEM_FRAME + )); + if (VersionHelper.isOrAbove1_21_6()) { + try { + Field happyGhastField = EntityType.class.getField("HAPPY_GHAST"); + EntityType happyGhast = (EntityType) happyGhastField.get(null); + set.add(happyGhast); + } catch (NoSuchFieldException | IllegalAccessException ignored) {} + } + return Collections.unmodifiableSet(set); + } private static void registerInteraction(Key key, QuadFunction, BlockData, BlockHitResult, Boolean> function) { var previous = INTERACTIONS.put(key, function); @@ -325,9 +345,10 @@ public class InteractUtils { public static boolean isEntityInteractable(Player player, Entity entity, Item item) { boolean isSneaking = player.isSneaking(); - if (entity.getType() == EntityType.PIGLIN && - item != null && - item.vanillaId().equals(Key.of("minecraft:gold_ingot"))) { + if (EntityUtils.isPiglinWithGoldIngot(entity, item)) { + return true; + } + if (EntityUtils.isHappyGhastRideable(entity) && !isSneaking) { return true; } return switch (entity) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/ItemTags.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/ItemTags.java index 1f35e3e90..62ab60190 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/ItemTags.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/ItemTags.java @@ -3,6 +3,11 @@ package net.momirealms.craftengine.bukkit.util; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistries; import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.VersionHelper; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.Tag; import java.util.HashMap; import java.util.Map; @@ -12,6 +17,7 @@ public class ItemTags { public static final Key AXES = Key.of("minecraft:axes"); public static final Key SWORDS = Key.of("minecraft:swords"); + public static final Tag ITEMS_HARNESSES = getHarnessTag(); private ItemTags() {} @@ -23,4 +29,13 @@ public class ItemTags { } return value; } + + public static Tag getHarnessTag() { + if (!VersionHelper.isOrAbove1_21_6()) return null; + try { + return Bukkit.getTag("items", NamespacedKey.minecraft("harnesses"), Material.class); + } catch (Exception e) { + return null; + } + } } From f7b1eb751f36029c9cc4f8684a0d4ddfa2ef2539 Mon Sep 17 00:00:00 2001 From: halogly Date: Fri, 18 Jul 2025 14:07:15 +0800 Subject: [PATCH 03/16] Fix interactable logic and update entity registration Corrects the logic for interactable checks in ItemEventListener to ensure proper event triggering. Removes sneaking check from chiseled bookshelf interaction and updates HAPPY_GHAST entity registration to use valueOf instead of reflection for compatibility with newer versions. --- .../bukkit/item/listener/ItemEventListener.java | 2 +- .../momirealms/craftengine/bukkit/util/InteractUtils.java | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) 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 8f2095acf..b0814f7d9 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 @@ -279,7 +279,7 @@ public class ItemEventListener implements Listener { .withParameter(DirectContextParameters.EVENT, dummy) ); CustomItem customItem = optionalCustomItem.get(); - if (!InteractUtils.isInteractable(player, blockData, hitResult, itemInHand) && !player.isSneaking()) { + if (!(InteractUtils.isInteractable(player, blockData, hitResult, itemInHand) && !player.isSneaking())) { customItem.execute(context, EventTrigger.RIGHT_CLICK); } if (dummy.isCancelled()) { 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 54e1aba40..87014ccae 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 @@ -94,7 +94,6 @@ public class InteractUtils { }); registerInteraction(BlockKeys.CHISELED_BOOKSHELF, (player, item, blockState, result) -> { Direction direction = result.getDirection(); - if (player.isSneaking()) return false; if (blockState instanceof ChiseledBookshelf chiseledBookshelf) { Direction facing = DirectionUtils.toDirection(chiseledBookshelf.getFacing()); return facing == direction; @@ -311,11 +310,7 @@ public class InteractUtils { EntityType.GLOW_ITEM_FRAME )); if (VersionHelper.isOrAbove1_21_6()) { - try { - Field happyGhastField = EntityType.class.getField("HAPPY_GHAST"); - EntityType happyGhast = (EntityType) happyGhastField.get(null); - set.add(happyGhast); - } catch (NoSuchFieldException | IllegalAccessException ignored) {} + set.add(EntityType.valueOf("HAPPY_GHAST")); } return Collections.unmodifiableSet(set); } From 870bd8171c5017cd661eca67a45934194ff2249d Mon Sep 17 00:00:00 2001 From: halogly Date: Fri, 18 Jul 2025 14:37:39 +0800 Subject: [PATCH 04/16] Remove unused imports in ItemEventListener and InteractUtils Cleaned up unused imports from ItemEventListener.java and InteractUtils.java to improve code readability and maintainability. --- .../craftengine/bukkit/item/listener/ItemEventListener.java | 2 -- .../net/momirealms/craftengine/bukkit/util/InteractUtils.java | 1 - 2 files changed, 3 deletions(-) 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 b0814f7d9..3b58cafd7 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 @@ -34,8 +34,6 @@ import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; -import org.bukkit.block.BlockState; -import org.bukkit.block.ChiseledBookshelf; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Openable; import org.bukkit.entity.Entity; 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 87014ccae..a3e3c6292 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 @@ -23,7 +23,6 @@ import org.bukkit.entity.minecart.RideableMinecart; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Nullable; -import java.lang.reflect.Field; import java.util.*; public class InteractUtils { From 76e98cda009e718f86794834fd58fc4c5feec353 Mon Sep 17 00:00:00 2001 From: halogly Date: Fri, 18 Jul 2025 14:38:46 +0800 Subject: [PATCH 05/16] Update ItemEventListener.java --- .../craftengine/bukkit/item/listener/ItemEventListener.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 3b58cafd7..9cd48510d 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 @@ -53,7 +53,10 @@ import org.bukkit.inventory.EnchantingInventory; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; public class ItemEventListener implements Listener { private final BukkitCraftEngine plugin; From 774a9a920774a5a16ee0d519ece2e73c43130f52 Mon Sep 17 00:00:00 2001 From: halogly Date: Fri, 18 Jul 2025 14:42:44 +0800 Subject: [PATCH 06/16] Refactor entity interaction and imports Replaced redundant event.getPlayer() call with local variable in ItemEventListener and updated import statements in EntityUtils for clarity and specificity. --- .../craftengine/bukkit/item/listener/ItemEventListener.java | 2 +- .../net/momirealms/craftengine/bukkit/util/EntityUtils.java | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) 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 9cd48510d..0eaa67cb5 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 @@ -69,7 +69,7 @@ public class ItemEventListener implements Listener { public void onInteractEntity(PlayerInteractEntityEvent event) { Player player = event.getPlayer(); Entity entity = event.getRightClicked(); - BukkitServerPlayer serverPlayer = this.plugin.adapt(event.getPlayer()); + BukkitServerPlayer serverPlayer = this.plugin.adapt(player); if (serverPlayer == null) return; InteractionHand hand = event.getHand() == EquipmentSlot.HAND ? InteractionHand.MAIN_HAND : InteractionHand.OFF_HAND; Item itemInHand = serverPlayer.getItemInHand(hand); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java index 0dfe4ec0d..070dd8ebe 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java @@ -8,7 +8,10 @@ import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.world.BlockPos; import org.bukkit.Location; import org.bukkit.World; -import org.bukkit.entity.*; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.inventory.EntityEquipment; import org.bukkit.inventory.EquipmentSlot; From 8a970fa2f3fa683f86abe273f769c4ac70262366 Mon Sep 17 00:00:00 2001 From: halogly Date: Fri, 18 Jul 2025 14:47:32 +0800 Subject: [PATCH 07/16] Update ItemEventListener.java --- .../item/listener/ItemEventListener.java | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) 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 0eaa67cb5..dc650c884 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 @@ -77,18 +77,17 @@ public class ItemEventListener implements Listener { if (ItemUtils.isEmpty(itemInHand)) return; Optional> optionalCustomItem = itemInHand.getCustomItem(); if (optionalCustomItem.isEmpty()) return; + if (InteractUtils.isEntityInteractable(player, entity, itemInHand)) return; - if (!InteractUtils.isEntityInteractable(player, entity, itemInHand)) { - Cancellable cancellable = Cancellable.of(event::isCancelled, event::setCancelled); - PlayerOptionalContext context = PlayerOptionalContext.of(serverPlayer, ContextHolder.builder() - .withOptionalParameter(DirectContextParameters.ITEM_IN_HAND, itemInHand) - .withParameter(DirectContextParameters.EVENT, cancellable) - .withParameter(DirectContextParameters.POSITION, LocationUtils.toWorldPosition(event.getRightClicked().getLocation())) - .withParameter(DirectContextParameters.HAND, hand) - ); - CustomItem customItem = optionalCustomItem.get(); - customItem.execute(context, EventTrigger.RIGHT_CLICK); - } + Cancellable cancellable = Cancellable.of(event::isCancelled, event::setCancelled); + PlayerOptionalContext context = PlayerOptionalContext.of(serverPlayer, ContextHolder.builder() + .withOptionalParameter(DirectContextParameters.ITEM_IN_HAND, itemInHand) + .withParameter(DirectContextParameters.EVENT, cancellable) + .withParameter(DirectContextParameters.POSITION, LocationUtils.toWorldPosition(event.getRightClicked().getLocation())) + .withParameter(DirectContextParameters.HAND, hand) + ); + CustomItem customItem = optionalCustomItem.get(); + customItem.execute(context, EventTrigger.RIGHT_CLICK); } @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) From 4d9d8169e8226e666159e2f955b68d3078e3d7ca Mon Sep 17 00:00:00 2001 From: halogly Date: Fri, 18 Jul 2025 16:25:37 +0800 Subject: [PATCH 08/16] =?UTF-8?q?=E5=88=86=E5=BC=80=E6=BD=9C=E8=A1=8C?= =?UTF-8?q?=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/util/InteractUtils.java | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) 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 a3e3c6292..99b3398a2 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 @@ -338,20 +338,22 @@ public class InteractUtils { } public static boolean isEntityInteractable(Player player, Entity entity, Item item) { - boolean isSneaking = player.isSneaking(); if (EntityUtils.isPiglinWithGoldIngot(entity, item)) { return true; } - if (EntityUtils.isHappyGhastRideable(entity) && !isSneaking) { - return true; + if (!player.isSneaking()) { + if (EntityUtils.isHappyGhastRideable(entity)) { + return true; + } + return switch (entity) { + case Boat ignored -> true; + case RideableMinecart ignored -> true; + case Steerable steerable -> steerable.hasSaddle(); + default -> INTERACTABLE_ENTITIES.contains(entity.getType()); + }; } - return switch (entity) { - case ChestBoat ignored -> true; - case Boat ignored -> !isSneaking; - case RideableMinecart ignored -> !isSneaking; - case Steerable steerable -> !isSneaking && steerable.hasSaddle(); - default -> INTERACTABLE_ENTITIES.contains(entity.getType()); - }; + return entity instanceof ChestBoat + || INTERACTABLE_ENTITIES.contains(entity.getType()); } public static boolean willConsume(Player player, BlockData state, BlockHitResult hit, @Nullable Item item) { From 9a1ebd8b58909dec0ae9e7669a64787a00828511 Mon Sep 17 00:00:00 2001 From: halogly Date: Mon, 21 Jul 2025 11:19:52 +0800 Subject: [PATCH 09/16] =?UTF-8?q?=E4=BF=AE=E6=94=B9tag=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=EF=BC=8C=E5=AE=9E=E4=BD=93=E4=BD=BF=E7=94=A8=E6=B3=A8=E5=86=8C?= =?UTF-8?q?=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../craftengine/bukkit/util/EntityUtils.java | 37 +++---- .../bukkit/util/InteractUtils.java | 96 ++++++++++--------- .../craftengine/bukkit/util/ItemTags.java | 10 -- .../craftengine/core/entity/EntityKeys.java | 34 +++++++ 4 files changed, 103 insertions(+), 74 deletions(-) create mode 100644 core/src/main/java/net/momirealms/craftengine/core/entity/EntityKeys.java diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java index 070dd8ebe..2772f445e 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.bukkit.util; +import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.core.item.Item; @@ -8,12 +9,8 @@ import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.world.BlockPos; import org.bukkit.Location; import org.bukkit.World; -import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; +import org.bukkit.entity.*; import org.bukkit.event.entity.CreatureSpawnEvent; -import org.bukkit.inventory.EntityEquipment; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; @@ -21,7 +18,8 @@ import java.util.function.Consumer; public class EntityUtils { - private EntityUtils() {} + private EntityUtils() { + } public static BlockPos getOnPos(Player player) { try { @@ -41,6 +39,13 @@ public class EntityUtils { } } + public static boolean isPetOwner(Player player, Entity entity) { + if (!(entity instanceof Sittable sittable)) return false; + return sittable instanceof Tameable tameable + && tameable.isTamed() + && tameable.getOwnerUniqueId() == player.getUniqueId(); + } + public static boolean isPiglinWithGoldIngot(Entity entity, Item item) { return entity.getType() == EntityType.PIGLIN && item != null && @@ -48,16 +53,12 @@ public class EntityUtils { } public static boolean isHappyGhastRideable(Entity entity) { - if (!VersionHelper.isOrAbove1_21_6() && - !entity.getType().name().equals("HAPPY_GHAST")) return false; - return entity instanceof LivingEntity livingEntity - && livingEntity.getEquipment() != null - && hasHarness(livingEntity.getEquipment()); + if (!VersionHelper.isOrAbove1_21_6()) return false; + if (entity instanceof LivingEntity living && entity.getType() == EntityType.HAPPY_GHAST) { + ItemStack bodyItem = living.getEquipment().getItem(EquipmentSlot.BODY); + Item wrapped = BukkitItemManager.instance().wrap(bodyItem); + return wrapped.is(Key.of("harnesses")); + } + return false; } - - public static boolean hasHarness(EntityEquipment equipment) { - ItemStack bodyItem = equipment.getItem(EquipmentSlot.BODY); - return ItemTags.ITEMS_HARNESSES != null && - ItemTags.ITEMS_HARNESSES.isTagged(bodyItem.getType()); - } -} +} \ No newline at end of file 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 99b3398a2..9ff03e35c 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 @@ -1,7 +1,9 @@ package net.momirealms.craftengine.bukkit.util; import net.momirealms.craftengine.bukkit.item.recipe.BukkitRecipeManager; +import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.core.block.BlockKeys; +import net.momirealms.craftengine.core.entity.EntityKeys; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemKeys; import net.momirealms.craftengine.core.item.recipe.RecipeTypes; @@ -29,7 +31,7 @@ public class InteractUtils { private static final Map, BlockData, BlockHitResult, Boolean>> INTERACTIONS = new HashMap<>(); private static final Map, BlockData, BlockHitResult, Boolean>> WILL_CONSUME = new HashMap<>(); private static final Key NOTE_BLOCK_TOP_INSTRUMENTS = Key.of("minecraft:noteblock_top_instruments"); - private static final Set INTERACTABLE_ENTITIES = createInteractableEntities(); + private static final Set INTERACTABLE_ENTITIES = new HashSet<>(); private InteractUtils() {} @@ -92,12 +94,8 @@ public class InteractUtils { ))) != null; }); registerInteraction(BlockKeys.CHISELED_BOOKSHELF, (player, item, blockState, result) -> { - Direction direction = result.getDirection(); - if (blockState instanceof ChiseledBookshelf chiseledBookshelf) { - Direction facing = DirectionUtils.toDirection(chiseledBookshelf.getFacing()); - return facing == direction; - } - return false; + if (!(blockState instanceof ChiseledBookshelf chiseledBookshelf)) return false; + return DirectionUtils.toDirection(chiseledBookshelf.getFacing()) == result.getDirection(); }); registerInteraction(BlockKeys.DECORATED_POT, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.HOPPER, (player, item, blockState, result) -> true); @@ -287,31 +285,35 @@ public class InteractUtils { result.getDirection() == Direction.UP && item.id().equals(ItemKeys.CACTUS)); } - private static Set createInteractableEntities() { - Set set = EnumSet.noneOf(EntityType.class); - set.addAll(Set.of( - EntityType.ALLAY, - EntityType.HORSE, - EntityType.ZOMBIE_HORSE, - EntityType.SKELETON_HORSE, - EntityType.DONKEY, - EntityType.MULE, - EntityType.VILLAGER, - EntityType.WANDERING_TRADER, - EntityType.LLAMA, - EntityType.TRADER_LLAMA, - EntityType.CAMEL, - EntityType.CHEST_MINECART, - EntityType.FURNACE_MINECART, - EntityType.HOPPER_MINECART, - EntityType.COMMAND_BLOCK_MINECART, - EntityType.ITEM_FRAME, - EntityType.GLOW_ITEM_FRAME - )); - if (VersionHelper.isOrAbove1_21_6()) { - set.add(EntityType.valueOf("HAPPY_GHAST")); + static { + registerInteractableEntity(EntityKeys.ALLAY); + registerInteractableEntity(EntityKeys.HORSE); + registerInteractableEntity(EntityKeys.ZOMBIE_HORSE); + registerInteractableEntity(EntityKeys.SKELETON_HORSE); + registerInteractableEntity(EntityKeys.DONKEY); + registerInteractableEntity(EntityKeys.MULE); + registerInteractableEntity(EntityKeys.VILLAGER); + registerInteractableEntity(EntityKeys.WANDERING_TRADER); + registerInteractableEntity(EntityKeys.LLAMA); + registerInteractableEntity(EntityKeys.TRADER_LLAMA); + registerInteractableEntity(EntityKeys.CAMEL); + registerInteractableEntity(EntityKeys.ITEM_FRAME); + registerInteractableEntity(EntityKeys.GLOW_ITEM_FRAME); + registerInteractableEntity(EntityKeys.INTERACTION); + if (VersionHelper.isOrAbove1_20_5()) { + registerInteractableEntity(EntityKeys.CHEST_MINECART); + registerInteractableEntity(EntityKeys.FURNACE_MINECART); + registerInteractableEntity(EntityKeys.HOPPER_MINECART); + registerInteractableEntity(EntityKeys.COMMAND_BLOCK_MINECART); + } else { + registerInteractableEntity(EntityKeys.MINECART_CHEST); + registerInteractableEntity(EntityKeys.MINECART_FURNACE); + registerInteractableEntity(EntityKeys.MINECART_HOPPER); + registerInteractableEntity(EntityKeys.MINECART_COMMAND); + } + if (VersionHelper.isOrAbove1_21_6()) { + registerInteractableEntity(EntityKeys.HAPPY_GHAST); } - return Collections.unmodifiableSet(set); } private static void registerInteraction(Key key, QuadFunction, BlockData, BlockHitResult, Boolean> function) { @@ -328,6 +330,13 @@ public class InteractUtils { } } + private static void registerInteractableEntity(Key key) { + var previous = INTERACTABLE_ENTITIES.add(key); + if (!previous) { + CraftEngine.instance().logger().warn("Duplicated interaction check: " + key); + } + } + public static boolean isInteractable(Player player, BlockData state, BlockHitResult hit, @Nullable Item item) { Key blockType = BlockStateUtils.getBlockOwnerIdFromData(state); if (INTERACTIONS.containsKey(blockType)) { @@ -338,22 +347,17 @@ public class InteractUtils { } public static boolean isEntityInteractable(Player player, Entity entity, Item item) { - if (EntityUtils.isPiglinWithGoldIngot(entity, item)) { - return true; - } +// Object entityType = FastNMS.INSTANCE.method$CraftEntityType$toNMSEntityType(entity.getType()); + Key entityType = Key.of(String.valueOf(entity.getType())); + if (EntityUtils.isPetOwner(player, entity)) return true; + if (EntityUtils.isPiglinWithGoldIngot(entity, item)) return true; if (!player.isSneaking()) { - if (EntityUtils.isHappyGhastRideable(entity)) { - return true; - } - return switch (entity) { - case Boat ignored -> true; - case RideableMinecart ignored -> true; - case Steerable steerable -> steerable.hasSaddle(); - default -> INTERACTABLE_ENTITIES.contains(entity.getType()); - }; + if (EntityUtils.isHappyGhastRideable(entity)) return true; + if (entity instanceof Boat) return true; + if (entity instanceof RideableMinecart) return true; + if (entity instanceof Steerable steerable && steerable.hasSaddle()) return true; } - return entity instanceof ChestBoat - || INTERACTABLE_ENTITIES.contains(entity.getType()); + return entity instanceof ChestBoat || INTERACTABLE_ENTITIES.contains(entityType); } public static boolean willConsume(Player player, BlockData state, BlockHitResult hit, @Nullable Item item) { @@ -365,7 +369,7 @@ public class InteractUtils { return false; } } - + private static boolean canEat(Player player, boolean ignoreHunger) { return ignoreHunger || player.isInvulnerable() || player.getFoodLevel() < 20; } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/ItemTags.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/ItemTags.java index 62ab60190..6028485a4 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/ItemTags.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/ItemTags.java @@ -17,7 +17,6 @@ public class ItemTags { public static final Key AXES = Key.of("minecraft:axes"); public static final Key SWORDS = Key.of("minecraft:swords"); - public static final Tag ITEMS_HARNESSES = getHarnessTag(); private ItemTags() {} @@ -29,13 +28,4 @@ public class ItemTags { } return value; } - - public static Tag getHarnessTag() { - if (!VersionHelper.isOrAbove1_21_6()) return null; - try { - return Bukkit.getTag("items", NamespacedKey.minecraft("harnesses"), Material.class); - } catch (Exception e) { - return null; - } - } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/EntityKeys.java b/core/src/main/java/net/momirealms/craftengine/core/entity/EntityKeys.java new file mode 100644 index 000000000..4b34d4c20 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/EntityKeys.java @@ -0,0 +1,34 @@ +package net.momirealms.craftengine.core.entity; + +import net.momirealms.craftengine.core.util.Key; + +public class EntityKeys { + private EntityKeys() {} + + public static final Key ALLAY = Key.of("minecraft:ALLAY"); + public static final Key HORSE = Key.of("minecraft:HORSE"); + public static final Key ZOMBIE_HORSE = Key.of("minecraft:ZOMBIE_HORSE"); + public static final Key SKELETON_HORSE = Key.of("minecraft:SKELETON_HORSE"); + public static final Key DONKEY = Key.of("minecraft:DONKEY"); + public static final Key MULE = Key.of("minecraft:MULE"); + public static final Key VILLAGER = Key.of("minecraft:VILLAGER"); + public static final Key WANDERING_TRADER = Key.of("minecraft:WANDERING_TRADER"); + public static final Key LLAMA = Key.of("minecraft:LLAMA"); + public static final Key TRADER_LLAMA = Key.of("minecraft:TRADER_LLAMA"); + public static final Key CAMEL = Key.of("minecraft:CAMEL"); + public static final Key ITEM_FRAME = Key.of("minecraft:ITEM_FRAME"); + public static final Key GLOW_ITEM_FRAME = Key.of("minecraft:GLOW_ITEM_FRAME"); + public static final Key INTERACTION = Key.of("minecraft:INTERACTION"); + // ≥1.20.5 + public static final Key CHEST_MINECART = Key.of("minecraft:CHEST_MINECART"); + 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"); + // <1.20.5 + public static final Key MINECART_CHEST = Key.of("minecraft:MINECART_CHEST"); + public static final Key MINECART_FURNACE = Key.of("minecraft:MINECART_FURNACE"); + public static final Key MINECART_HOPPER = Key.of("minecraft:MINECART_HOPPER"); + public static final Key MINECART_COMMAND = Key.of("minecraft:MINECART_COMMAND"); + // ≥1.21.6 + public static final Key HAPPY_GHAST = Key.of("minecraft:HAPPY_GHAST"); +} From e7a2386466b78a14e1407d7f68dfc5df371681de Mon Sep 17 00:00:00 2001 From: halogly Date: Tue, 22 Jul 2025 18:08:19 +0800 Subject: [PATCH 10/16] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E4=B8=80=E5=A0=86if?= =?UTF-8?q?=E5=88=A4=E6=96=AD=EF=BC=8C=E4=BD=BF=E7=94=A8=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E5=A4=84=E7=90=86=E5=8F=AF=E4=BA=A4=E4=BA=92=E5=AE=9E=E4=BD=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/util/InteractUtils.java | 114 ++++++++++-------- .../craftengine/core/entity/EntityKeys.java | 33 ++++- 2 files changed, 97 insertions(+), 50 deletions(-) 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 9ff03e35c..ea50ffd26 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 @@ -14,14 +14,13 @@ import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.util.Direction; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.QuadFunction; -import net.momirealms.craftengine.core.util.VersionHelper; +import net.momirealms.craftengine.core.util.TriFunction; import net.momirealms.craftengine.core.world.BlockHitResult; import net.momirealms.craftengine.core.world.BlockPos; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.type.Bell; import org.bukkit.block.data.type.ChiseledBookshelf; import org.bukkit.entity.*; -import org.bukkit.entity.minecart.RideableMinecart; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Nullable; @@ -31,7 +30,7 @@ public class InteractUtils { private static final Map, BlockData, BlockHitResult, Boolean>> INTERACTIONS = new HashMap<>(); private static final Map, BlockData, BlockHitResult, Boolean>> WILL_CONSUME = new HashMap<>(); private static final Key NOTE_BLOCK_TOP_INSTRUMENTS = Key.of("minecraft:noteblock_top_instruments"); - private static final Set INTERACTABLE_ENTITIES = new HashSet<>(); + private static final Map, Boolean>> ENTITY_INTERACTIONS = new HashMap<>(); private InteractUtils() {} @@ -286,34 +285,63 @@ public class InteractUtils { } static { - registerInteractableEntity(EntityKeys.ALLAY); - registerInteractableEntity(EntityKeys.HORSE); - registerInteractableEntity(EntityKeys.ZOMBIE_HORSE); - registerInteractableEntity(EntityKeys.SKELETON_HORSE); - registerInteractableEntity(EntityKeys.DONKEY); - registerInteractableEntity(EntityKeys.MULE); - registerInteractableEntity(EntityKeys.VILLAGER); - registerInteractableEntity(EntityKeys.WANDERING_TRADER); - registerInteractableEntity(EntityKeys.LLAMA); - registerInteractableEntity(EntityKeys.TRADER_LLAMA); - registerInteractableEntity(EntityKeys.CAMEL); - registerInteractableEntity(EntityKeys.ITEM_FRAME); - registerInteractableEntity(EntityKeys.GLOW_ITEM_FRAME); - registerInteractableEntity(EntityKeys.INTERACTION); - if (VersionHelper.isOrAbove1_20_5()) { - registerInteractableEntity(EntityKeys.CHEST_MINECART); - registerInteractableEntity(EntityKeys.FURNACE_MINECART); - registerInteractableEntity(EntityKeys.HOPPER_MINECART); - registerInteractableEntity(EntityKeys.COMMAND_BLOCK_MINECART); - } else { - registerInteractableEntity(EntityKeys.MINECART_CHEST); - registerInteractableEntity(EntityKeys.MINECART_FURNACE); - registerInteractableEntity(EntityKeys.MINECART_HOPPER); - registerInteractableEntity(EntityKeys.MINECART_COMMAND); - } - if (VersionHelper.isOrAbove1_21_6()) { - registerInteractableEntity(EntityKeys.HAPPY_GHAST); - } + // 忽视潜行的交互实体 + registerEntityInteraction(EntityKeys.ALLAY, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.HORSE, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.ZOMBIE_HORSE, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.SKELETON_HORSE, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.DONKEY, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.MULE, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.VILLAGER, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.WANDERING_TRADER, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.LLAMA, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.TRADER_LLAMA, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.CAMEL, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.ITEM_FRAME, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.GLOW_ITEM_FRAME, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.INTERACTION, (player, entity, item) -> true); + // 潜行时不可交互 + registerEntityInteraction(EntityKeys.ACACIA_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityKeys.BAMBOO_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityKeys.BIRCH_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityKeys.CHERRY_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityKeys.DARK_OAK_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityKeys.JUNGLE_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityKeys.MANGROVE_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityKeys.OAK_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityKeys.SPRUCE_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityKeys.MINECART, (player, entity, item) -> !player.isSneaking()); + // 始终可交互的箱子类船车 + registerEntityInteraction(EntityKeys.ACACIA_CHEST_BOAT, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.BAMBOO_CHEST_BOAT, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.BIRCH_CHEST_BOAT, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.CHERRY_CHEST_BOAT, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.DARK_OAK_CHEST_BOAT, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.JUNGLE_CHEST_BOAT, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.MANGROVE_CHEST_BOAT, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.OAK_CHEST_BOAT, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.SPRUCE_CHEST_BOAT, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.CHEST_MINECART, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.FURNACE_MINECART, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.HOPPER_MINECART, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.COMMAND_BLOCK_MINECART, (player, entity, item) -> true); + //<1.20.5 + registerEntityInteraction(EntityKeys.MINECART_CHEST, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.MINECART_HOPPER, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.MINECART_FURNACE, (player, entity, item) -> true); + registerEntityInteraction(EntityKeys.MINECART_COMMAND, (player, entity, item) -> true); + // 有鞍 + 非潜行可交互(如猪、炽足兽) + registerEntityInteraction(EntityKeys.PIG, (player, entity, item) -> + entity instanceof Steerable steerable && steerable.hasSaddle() && !player.isSneaking()); + registerEntityInteraction(EntityKeys.STRIDER, (player, entity, item) -> + entity instanceof Steerable steerable && steerable.hasSaddle() && !player.isSneaking()); + // 是宠物,且主人是玩家(忽视潜行) + registerEntityInteraction(EntityKeys.WOLF, (player, entity, item) -> EntityUtils.isPetOwner(player, entity)); + registerEntityInteraction(EntityKeys.CAT, (player, entity, item) -> EntityUtils.isPetOwner(player, entity)); + registerEntityInteraction(EntityKeys.PARROT, (player, entity, item) -> EntityUtils.isPetOwner(player, entity)); + // 快乐恶魂(装备挽具、受潜行影响) + registerEntityInteraction(EntityKeys.HAPPY_GHAST, (player, entity, item) -> + EntityUtils.isHappyGhastRideable(entity) && !player.isSneaking()); } private static void registerInteraction(Key key, QuadFunction, BlockData, BlockHitResult, Boolean> function) { @@ -330,10 +358,10 @@ public class InteractUtils { } } - private static void registerInteractableEntity(Key key) { - var previous = INTERACTABLE_ENTITIES.add(key); - if (!previous) { - CraftEngine.instance().logger().warn("Duplicated interaction check: " + key); + 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); } } @@ -346,18 +374,10 @@ public class InteractUtils { } } - public static boolean isEntityInteractable(Player player, Entity entity, Item item) { -// Object entityType = FastNMS.INSTANCE.method$CraftEntityType$toNMSEntityType(entity.getType()); - Key entityType = Key.of(String.valueOf(entity.getType())); - if (EntityUtils.isPetOwner(player, entity)) return true; - if (EntityUtils.isPiglinWithGoldIngot(entity, item)) return true; - if (!player.isSneaking()) { - if (EntityUtils.isHappyGhastRideable(entity)) return true; - if (entity instanceof Boat) return true; - if (entity instanceof RideableMinecart) return true; - if (entity instanceof Steerable steerable && steerable.hasSaddle()) return true; - } - return entity instanceof ChestBoat || INTERACTABLE_ENTITIES.contains(entityType); + public static boolean isEntityInteractable(Player player, Entity entity, @Nullable Item item) { + Key key = Key.of(String.valueOf(entity.getType())); + TriFunction, Boolean> func = ENTITY_INTERACTIONS.get(key); + return func != null && func.apply(player, entity, item); } public static boolean willConsume(Player player, BlockData state, BlockHitResult hit, @Nullable Item item) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/EntityKeys.java b/core/src/main/java/net/momirealms/craftengine/core/entity/EntityKeys.java index 4b34d4c20..8691c0912 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/EntityKeys.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/EntityKeys.java @@ -19,16 +19,43 @@ public class EntityKeys { public static final Key ITEM_FRAME = Key.of("minecraft:ITEM_FRAME"); public static final Key GLOW_ITEM_FRAME = Key.of("minecraft:GLOW_ITEM_FRAME"); public static final Key INTERACTION = Key.of("minecraft:INTERACTION"); - // ≥1.20.5 + + public static final Key ACACIA_BOAT = Key.of("minecraft:ACACIA_BOAT"); + public static final Key BAMBOO_BOAT = Key.of("minecraft:BAMBOO_BOAT"); + public static final Key BIRCH_BOAT = Key.of("minecraft:BIRCH_BOAT"); + public static final Key CHERRY_BOAT = Key.of("minecraft:CHERRY_BOAT"); + public static final Key DARK_OAK_BOAT = Key.of("minecraft:DARK_OAK_BOAT"); + public static final Key JUNGLE_BOAT = Key.of("minecraft:JUNGLE_BOAT"); + public static final Key MANGROVE_BOAT = Key.of("minecraft:MANGROVE_BOAT"); + public static final Key OAK_BOAT = Key.of("minecraft:OAK_BOAT"); + public static final Key SPRUCE_BOAT = Key.of("minecraft:SPRUCE_BOAT"); + public static final Key MINECART = Key.of("minecraft:MINECART"); + + public static final Key ACACIA_CHEST_BOAT = Key.of("minecraft:ACACIA_CHEST_BOAT"); + public static final Key BAMBOO_CHEST_BOAT = Key.of("minecraft:BAMBOO_CHEST_BOAT"); + public static final Key BIRCH_CHEST_BOAT = Key.of("minecraft:BIRCH_CHEST_BOAT"); + public static final Key CHERRY_CHEST_BOAT = Key.of("minecraft:CHERRY_CHEST_BOAT"); + public static final Key DARK_OAK_CHEST_BOAT = Key.of("minecraft:DARK_OAK_CHEST_BOAT"); + public static final Key JUNGLE_CHEST_BOAT = Key.of("minecraft:JUNGLE_CHEST_BOAT"); + public static final Key MANGROVE_CHEST_BOAT = Key.of("minecraft:MANGROVE_CHEST_BOAT"); + public static final Key OAK_CHEST_BOAT = Key.of("minecraft:OAK_CHEST_BOAT"); + public static final Key SPRUCE_CHEST_BOAT = Key.of("minecraft:SPRUCE_CHEST_BOAT"); public static final Key CHEST_MINECART = Key.of("minecraft:CHEST_MINECART"); 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"); - // <1.20.5 + //<1.20.5 public static final Key MINECART_CHEST = Key.of("minecraft:MINECART_CHEST"); public static final Key MINECART_FURNACE = Key.of("minecraft:MINECART_FURNACE"); public static final Key MINECART_HOPPER = Key.of("minecraft:MINECART_HOPPER"); public static final Key MINECART_COMMAND = Key.of("minecraft:MINECART_COMMAND"); - // ≥1.21.6 + + public static final Key PIG = Key.of("minecraft:PIG"); + public static final Key STRIDER = Key.of("minecraft:STRIDER"); + + public static final Key WOLF = Key.of("minecraft:WOLF"); + public static final Key CAT = Key.of("minecraft:CAT"); + public static final Key PARROT = Key.of("minecraft:PARROT"); + public static final Key HAPPY_GHAST = Key.of("minecraft:HAPPY_GHAST"); } From fa9feb3b8b74bb3516307705a77f67ec5c2aaa15 Mon Sep 17 00:00:00 2001 From: halogly Date: Tue, 22 Jul 2025 18:09:48 +0800 Subject: [PATCH 11/16] =?UTF-8?q?=E5=88=A0=E9=99=A4=E9=87=91=E9=94=AD?= =?UTF-8?q?=E6=A3=80=E6=B5=8B=EF=BC=8C=E6=B2=A1=E5=BF=85=E8=A6=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../net/momirealms/craftengine/bukkit/util/EntityUtils.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java index 2772f445e..a0ddb917c 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java @@ -46,12 +46,6 @@ public class EntityUtils { && tameable.getOwnerUniqueId() == player.getUniqueId(); } - public static boolean isPiglinWithGoldIngot(Entity entity, Item item) { - return entity.getType() == EntityType.PIGLIN && - item != null && - item.vanillaId().equals(Key.of("minecraft:gold_ingot")); - } - public static boolean isHappyGhastRideable(Entity entity) { if (!VersionHelper.isOrAbove1_21_6()) return false; if (entity instanceof LivingEntity living && entity.getType() == EntityType.HAPPY_GHAST) { From 9f38dd49c6111cc7b1cb3bb5ef16837f7ca72c0d Mon Sep 17 00:00:00 2001 From: halogly Date: Tue, 22 Jul 2025 18:11:52 +0800 Subject: [PATCH 12/16] =?UTF-8?q?=E5=87=8F=E5=B0=91=E5=AE=A0=E7=89=A9?= =?UTF-8?q?=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../net/momirealms/craftengine/bukkit/util/EntityUtils.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java index a0ddb917c..5d820708d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java @@ -40,8 +40,7 @@ public class EntityUtils { } public static boolean isPetOwner(Player player, Entity entity) { - if (!(entity instanceof Sittable sittable)) return false; - return sittable instanceof Tameable tameable + return entity instanceof Tameable tameable && tameable.isTamed() && tameable.getOwnerUniqueId() == player.getUniqueId(); } From 86c014b252e37362d93f37dce1105d50d96cecef Mon Sep 17 00:00:00 2001 From: halogly Date: Tue, 22 Jul 2025 19:24:22 +0800 Subject: [PATCH 13/16] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E5=BA=94=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../craftengine/bukkit/util/EntityUtils.java | 21 ------ .../bukkit/util/InteractUtils.java | 66 ++++++++++--------- 2 files changed, 36 insertions(+), 51 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java index 5d820708d..e7fe96bb1 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java @@ -1,18 +1,13 @@ package net.momirealms.craftengine.bukkit.util; -import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; -import net.momirealms.craftengine.core.item.Item; -import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.world.BlockPos; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.*; import org.bukkit.event.entity.CreatureSpawnEvent; -import org.bukkit.inventory.EquipmentSlot; -import org.bukkit.inventory.ItemStack; import java.util.function.Consumer; @@ -38,20 +33,4 @@ public class EntityUtils { return LegacyEntityUtils.spawnEntity(world, loc, type, function); } } - - public static boolean isPetOwner(Player player, Entity entity) { - return entity instanceof Tameable tameable - && tameable.isTamed() - && tameable.getOwnerUniqueId() == player.getUniqueId(); - } - - public static boolean isHappyGhastRideable(Entity entity) { - if (!VersionHelper.isOrAbove1_21_6()) return false; - if (entity instanceof LivingEntity living && entity.getType() == EntityType.HAPPY_GHAST) { - ItemStack bodyItem = living.getEquipment().getItem(EquipmentSlot.BODY); - Item wrapped = BukkitItemManager.instance().wrap(bodyItem); - return wrapped.is(Key.of("harnesses")); - } - return false; - } } \ No newline at end of file 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 ea50ffd26..0f93adcd7 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 @@ -1,7 +1,7 @@ package net.momirealms.craftengine.bukkit.util; +import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.item.recipe.BukkitRecipeManager; -import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.core.block.BlockKeys; import net.momirealms.craftengine.core.entity.EntityKeys; import net.momirealms.craftengine.core.item.Item; @@ -11,16 +11,14 @@ import net.momirealms.craftengine.core.item.recipe.UniqueIdItem; import net.momirealms.craftengine.core.item.recipe.input.SingleItemInput; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.config.Config; -import net.momirealms.craftengine.core.util.Direction; -import net.momirealms.craftengine.core.util.Key; -import net.momirealms.craftengine.core.util.QuadFunction; -import net.momirealms.craftengine.core.util.TriFunction; +import net.momirealms.craftengine.core.util.*; import net.momirealms.craftengine.core.world.BlockHitResult; import net.momirealms.craftengine.core.world.BlockPos; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.type.Bell; import org.bukkit.block.data.type.ChiseledBookshelf; import org.bukkit.entity.*; +import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Nullable; @@ -285,7 +283,31 @@ public class InteractUtils { } static { - // 忽视潜行的交互实体 + // 有鞍 + 非潜行可交互(如猪、炽足兽) + registerEntityInteraction(EntityKeys.PIG, (player, entity, item) -> hasSaddle(player, entity) && !player.isSneaking()); + registerEntityInteraction(EntityKeys.STRIDER, (player, entity, item) -> hasSaddle(player, entity) && !player.isSneaking()); + registerEntityInteraction(EntityKeys.WOLF, (player, entity, item) -> isPetOwner(player, entity)); + registerEntityInteraction(EntityKeys.CAT, (player, entity, item) -> isPetOwner(player, entity)); + registerEntityInteraction(EntityKeys.PARROT, (player, entity, item) -> isPetOwner(player, entity)); + registerEntityInteraction(EntityKeys.ACACIA_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityKeys.BAMBOO_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityKeys.BIRCH_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityKeys.CHERRY_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityKeys.DARK_OAK_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityKeys.JUNGLE_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityKeys.MANGROVE_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityKeys.OAK_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityKeys.SPRUCE_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityKeys.MINECART, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityKeys.HAPPY_GHAST, (player, entity, item) -> { + if (!VersionHelper.isOrAbove1_21_6()) return false; + if (entity instanceof LivingEntity living && entity.getType() == EntityType.HAPPY_GHAST) { + ItemStack bodyItem = living.getEquipment().getItem(EquipmentSlot.BODY); + Item wrapped = BukkitItemManager.instance().wrap(bodyItem); + return wrapped.is(Key.of("harnesses")); + } + return false; + }); registerEntityInteraction(EntityKeys.ALLAY, (player, entity, item) -> true); registerEntityInteraction(EntityKeys.HORSE, (player, entity, item) -> true); registerEntityInteraction(EntityKeys.ZOMBIE_HORSE, (player, entity, item) -> true); @@ -300,18 +322,6 @@ public class InteractUtils { registerEntityInteraction(EntityKeys.ITEM_FRAME, (player, entity, item) -> true); registerEntityInteraction(EntityKeys.GLOW_ITEM_FRAME, (player, entity, item) -> true); registerEntityInteraction(EntityKeys.INTERACTION, (player, entity, item) -> true); - // 潜行时不可交互 - registerEntityInteraction(EntityKeys.ACACIA_BOAT, (player, entity, item) -> !player.isSneaking()); - registerEntityInteraction(EntityKeys.BAMBOO_BOAT, (player, entity, item) -> !player.isSneaking()); - registerEntityInteraction(EntityKeys.BIRCH_BOAT, (player, entity, item) -> !player.isSneaking()); - registerEntityInteraction(EntityKeys.CHERRY_BOAT, (player, entity, item) -> !player.isSneaking()); - registerEntityInteraction(EntityKeys.DARK_OAK_BOAT, (player, entity, item) -> !player.isSneaking()); - registerEntityInteraction(EntityKeys.JUNGLE_BOAT, (player, entity, item) -> !player.isSneaking()); - registerEntityInteraction(EntityKeys.MANGROVE_BOAT, (player, entity, item) -> !player.isSneaking()); - registerEntityInteraction(EntityKeys.OAK_BOAT, (player, entity, item) -> !player.isSneaking()); - registerEntityInteraction(EntityKeys.SPRUCE_BOAT, (player, entity, item) -> !player.isSneaking()); - registerEntityInteraction(EntityKeys.MINECART, (player, entity, item) -> !player.isSneaking()); - // 始终可交互的箱子类船车 registerEntityInteraction(EntityKeys.ACACIA_CHEST_BOAT, (player, entity, item) -> true); registerEntityInteraction(EntityKeys.BAMBOO_CHEST_BOAT, (player, entity, item) -> true); registerEntityInteraction(EntityKeys.BIRCH_CHEST_BOAT, (player, entity, item) -> true); @@ -330,18 +340,6 @@ public class InteractUtils { registerEntityInteraction(EntityKeys.MINECART_HOPPER, (player, entity, item) -> true); registerEntityInteraction(EntityKeys.MINECART_FURNACE, (player, entity, item) -> true); registerEntityInteraction(EntityKeys.MINECART_COMMAND, (player, entity, item) -> true); - // 有鞍 + 非潜行可交互(如猪、炽足兽) - registerEntityInteraction(EntityKeys.PIG, (player, entity, item) -> - entity instanceof Steerable steerable && steerable.hasSaddle() && !player.isSneaking()); - registerEntityInteraction(EntityKeys.STRIDER, (player, entity, item) -> - entity instanceof Steerable steerable && steerable.hasSaddle() && !player.isSneaking()); - // 是宠物,且主人是玩家(忽视潜行) - registerEntityInteraction(EntityKeys.WOLF, (player, entity, item) -> EntityUtils.isPetOwner(player, entity)); - registerEntityInteraction(EntityKeys.CAT, (player, entity, item) -> EntityUtils.isPetOwner(player, entity)); - registerEntityInteraction(EntityKeys.PARROT, (player, entity, item) -> EntityUtils.isPetOwner(player, entity)); - // 快乐恶魂(装备挽具、受潜行影响) - registerEntityInteraction(EntityKeys.HAPPY_GHAST, (player, entity, item) -> - EntityUtils.isHappyGhastRideable(entity) && !player.isSneaking()); } private static void registerInteraction(Key key, QuadFunction, BlockData, BlockHitResult, Boolean> function) { @@ -393,4 +391,12 @@ public class InteractUtils { private static boolean canEat(Player player, boolean ignoreHunger) { return ignoreHunger || player.isInvulnerable() || player.getFoodLevel() < 20; } + + public static boolean hasSaddle(Player player, Entity entity) { + return entity instanceof Steerable steerable && steerable.hasSaddle() && !player.isSneaking(); + } + + public static boolean isPetOwner(Player player, Entity entity) { + return entity instanceof Tameable tameable && tameable.isTamed() && tameable.getOwnerUniqueId() == player.getUniqueId(); + } } From c2e34ec965d471ea427f415f5ff2fe42d78dd7b9 Mon Sep 17 00:00:00 2001 From: halogly Date: Wed, 23 Jul 2025 00:04:23 +0800 Subject: [PATCH 14/16] =?UTF-8?q?=E5=B0=8F=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/util/InteractUtils.java | 10 ++--- .../craftengine/core/entity/EntityKeys.java | 38 +++++++++---------- .../craftengine/core/item/ItemKeys.java | 1 + 3 files changed, 23 insertions(+), 26 deletions(-) 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 0f93adcd7..2809910b7 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 @@ -27,8 +27,8 @@ import java.util.*; public class InteractUtils { private static final Map, BlockData, BlockHitResult, Boolean>> INTERACTIONS = new HashMap<>(); private static final Map, BlockData, BlockHitResult, Boolean>> WILL_CONSUME = new HashMap<>(); - private static final Key NOTE_BLOCK_TOP_INSTRUMENTS = Key.of("minecraft:noteblock_top_instruments"); private static final Map, Boolean>> ENTITY_INTERACTIONS = new HashMap<>(); + private static final Key NOTE_BLOCK_TOP_INSTRUMENTS = Key.of("minecraft:noteblock_top_instruments"); private InteractUtils() {} @@ -283,7 +283,7 @@ public class InteractUtils { } static { - // 有鞍 + 非潜行可交互(如猪、炽足兽) + registerEntityInteraction(EntityKeys.PIGLIN, (player, entity, item) -> item != null && item.vanillaId().equals(ItemKeys.GOLD_INGOT)); registerEntityInteraction(EntityKeys.PIG, (player, entity, item) -> hasSaddle(player, entity) && !player.isSneaking()); registerEntityInteraction(EntityKeys.STRIDER, (player, entity, item) -> hasSaddle(player, entity) && !player.isSneaking()); registerEntityInteraction(EntityKeys.WOLF, (player, entity, item) -> isPetOwner(player, entity)); @@ -301,8 +301,8 @@ public class InteractUtils { registerEntityInteraction(EntityKeys.MINECART, (player, entity, item) -> !player.isSneaking()); registerEntityInteraction(EntityKeys.HAPPY_GHAST, (player, entity, item) -> { if (!VersionHelper.isOrAbove1_21_6()) return false; - if (entity instanceof LivingEntity living && entity.getType() == EntityType.HAPPY_GHAST) { - ItemStack bodyItem = living.getEquipment().getItem(EquipmentSlot.BODY); + if (entity instanceof HappyGhast happyGhast) { + ItemStack bodyItem = happyGhast.getEquipment().getItem(EquipmentSlot.BODY); Item wrapped = BukkitItemManager.instance().wrap(bodyItem); return wrapped.is(Key.of("harnesses")); } @@ -397,6 +397,6 @@ public class InteractUtils { } public static boolean isPetOwner(Player player, Entity entity) { - return entity instanceof Tameable tameable && tameable.isTamed() && tameable.getOwnerUniqueId() == player.getUniqueId(); + return entity instanceof Tameable tameable && tameable.isTamed() && player.getUniqueId().equals(tameable.getOwnerUniqueId()); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/EntityKeys.java b/core/src/main/java/net/momirealms/craftengine/core/entity/EntityKeys.java index 8691c0912..6f075e3d6 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/EntityKeys.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/EntityKeys.java @@ -5,6 +5,23 @@ import net.momirealms.craftengine.core.util.Key; public class EntityKeys { private EntityKeys() {} + public static final Key PIG = Key.of("minecraft:PIG"); + public static final Key STRIDER = Key.of("minecraft:STRIDER"); + public static final Key WOLF = Key.of("minecraft:WOLF"); + public static final Key CAT = Key.of("minecraft:CAT"); + public static final Key PARROT = Key.of("minecraft:PARROT"); + public static final Key ACACIA_BOAT = Key.of("minecraft:ACACIA_BOAT"); + public static final Key BAMBOO_BOAT = Key.of("minecraft:BAMBOO_BOAT"); + public static final Key BIRCH_BOAT = Key.of("minecraft:BIRCH_BOAT"); + public static final Key CHERRY_BOAT = Key.of("minecraft:CHERRY_BOAT"); + public static final Key DARK_OAK_BOAT = Key.of("minecraft:DARK_OAK_BOAT"); + public static final Key JUNGLE_BOAT = Key.of("minecraft:JUNGLE_BOAT"); + public static final Key MANGROVE_BOAT = Key.of("minecraft:MANGROVE_BOAT"); + public static final Key OAK_BOAT = Key.of("minecraft:OAK_BOAT"); + public static final Key SPRUCE_BOAT = Key.of("minecraft:SPRUCE_BOAT"); + public static final Key MINECART = Key.of("minecraft:MINECART"); + public static final Key HAPPY_GHAST = Key.of("minecraft:HAPPY_GHAST"); + public static final Key PIGLIN = Key.of("minecraft:PIGLIN"); public static final Key ALLAY = Key.of("minecraft:ALLAY"); public static final Key HORSE = Key.of("minecraft:HORSE"); public static final Key ZOMBIE_HORSE = Key.of("minecraft:ZOMBIE_HORSE"); @@ -19,18 +36,6 @@ public class EntityKeys { public static final Key ITEM_FRAME = Key.of("minecraft:ITEM_FRAME"); public static final Key GLOW_ITEM_FRAME = Key.of("minecraft:GLOW_ITEM_FRAME"); public static final Key INTERACTION = Key.of("minecraft:INTERACTION"); - - public static final Key ACACIA_BOAT = Key.of("minecraft:ACACIA_BOAT"); - public static final Key BAMBOO_BOAT = Key.of("minecraft:BAMBOO_BOAT"); - public static final Key BIRCH_BOAT = Key.of("minecraft:BIRCH_BOAT"); - public static final Key CHERRY_BOAT = Key.of("minecraft:CHERRY_BOAT"); - public static final Key DARK_OAK_BOAT = Key.of("minecraft:DARK_OAK_BOAT"); - public static final Key JUNGLE_BOAT = Key.of("minecraft:JUNGLE_BOAT"); - public static final Key MANGROVE_BOAT = Key.of("minecraft:MANGROVE_BOAT"); - public static final Key OAK_BOAT = Key.of("minecraft:OAK_BOAT"); - public static final Key SPRUCE_BOAT = Key.of("minecraft:SPRUCE_BOAT"); - public static final Key MINECART = Key.of("minecraft:MINECART"); - public static final Key ACACIA_CHEST_BOAT = Key.of("minecraft:ACACIA_CHEST_BOAT"); public static final Key BAMBOO_CHEST_BOAT = Key.of("minecraft:BAMBOO_CHEST_BOAT"); public static final Key BIRCH_CHEST_BOAT = Key.of("minecraft:BIRCH_CHEST_BOAT"); @@ -49,13 +54,4 @@ public class EntityKeys { public static final Key MINECART_FURNACE = Key.of("minecraft:MINECART_FURNACE"); public static final Key MINECART_HOPPER = Key.of("minecraft:MINECART_HOPPER"); public static final Key MINECART_COMMAND = Key.of("minecraft:MINECART_COMMAND"); - - public static final Key PIG = Key.of("minecraft:PIG"); - public static final Key STRIDER = Key.of("minecraft:STRIDER"); - - public static final Key WOLF = Key.of("minecraft:WOLF"); - public static final Key CAT = Key.of("minecraft:CAT"); - public static final Key PARROT = Key.of("minecraft:PARROT"); - - public static final Key HAPPY_GHAST = Key.of("minecraft:HAPPY_GHAST"); } 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 89916d9e3..7fc6b799a 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 @@ -33,6 +33,7 @@ public class ItemKeys { public static final Key BARRIER = Key.of("minecraft:barrier"); public static final Key CACTUS = Key.of("minecraft:cactus"); public static final Key REDSTONE = Key.of("minecraft:redstone"); + public static final Key GOLD_INGOT = Key.of("minecraft:gold_ingot"); public static final Key[] AXES = new Key[] { WOODEN_AXE, STONE_AXE, IRON_AXE, GOLDEN_AXE, DIAMOND_AXE, NETHERITE_AXE From bb3c11016c2dfde38dd353668ad271924c2f198d Mon Sep 17 00:00:00 2001 From: halogly Date: Thu, 24 Jul 2025 17:51:04 +0800 Subject: [PATCH 15/16] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=9B=B4=E5=A4=9A?= =?UTF-8?q?=E5=AE=9E=E4=BD=93=E4=BA=A4=E4=BA=92=EF=BC=8C=E8=A1=A5=E5=85=85?= =?UTF-8?q?=E4=B8=80=E4=BA=9B=E5=8F=AF=E4=BA=A4=E4=BA=92=E6=96=B9=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/util/InteractUtils.java | 92 +++++++++++++++---- .../craftengine/core/block/BlockKeys.java | 14 +++ .../craftengine/core/entity/EntityKeys.java | 24 +++++ .../craftengine/core/item/ItemKeys.java | 5 + 4 files changed, 119 insertions(+), 16 deletions(-) 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 2809910b7..39cbba3da 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 @@ -1,5 +1,6 @@ package net.momirealms.craftengine.bukkit.util; +import io.papermc.paper.entity.Shearable; import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.item.recipe.BukkitRecipeManager; import net.momirealms.craftengine.core.block.BlockKeys; @@ -52,6 +53,9 @@ public class InteractUtils { 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.BEE_NEST, (player, item, blockState, result) -> item.vanillaId().equals(ItemKeys.SHEARS) || item.vanillaId().equals(ItemKeys.GLASS_BOTTLE)); + registerInteraction(BlockKeys.BEEHIVE, (player, item, blockState, result) -> item.vanillaId().equals(ItemKeys.SHEARS) || item.vanillaId().equals(ItemKeys.GLASS_BOTTLE)); + registerInteraction(BlockKeys.POWDER_SNOW, (player, item, blockState, result) -> item.vanillaId().equals(ItemKeys.BUCKET)); registerInteraction(BlockKeys.BELL, (player, item, blockState, result) -> { Direction direction = result.getDirection(); BlockPos pos = result.getBlockPos(); @@ -270,9 +274,14 @@ public class InteractUtils { 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); - registerInteraction(BlockKeys.REPEATING_COMMAND_BLOCK, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.CHAIN_COMMAND_BLOCK, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.COMMAND_BLOCK, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.CHAIN_COMMAND_BLOCK, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.REPEATING_COMMAND_BLOCK, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.JIGSAW, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.STRUCTURE_BLOCK, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.TEST_INSTANCE_BLOCK, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.TEST_BLOCK, (player, item, blockState, result) -> true); + registerInteraction(BlockKeys.LIGHT, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.REDSTONE_ORE, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.DEEPSLATE_REDSTONE_ORE, (player, item, blockState, result) -> true); } @@ -283,12 +292,53 @@ public class InteractUtils { } static { - registerEntityInteraction(EntityKeys.PIGLIN, (player, entity, item) -> item != null && item.vanillaId().equals(ItemKeys.GOLD_INGOT)); - registerEntityInteraction(EntityKeys.PIG, (player, entity, item) -> hasSaddle(player, entity) && !player.isSneaking()); - registerEntityInteraction(EntityKeys.STRIDER, (player, entity, item) -> hasSaddle(player, entity) && !player.isSneaking()); - registerEntityInteraction(EntityKeys.WOLF, (player, entity, item) -> isPetOwner(player, entity)); - registerEntityInteraction(EntityKeys.CAT, (player, entity, item) -> isPetOwner(player, entity)); - registerEntityInteraction(EntityKeys.PARROT, (player, entity, item) -> isPetOwner(player, entity)); + registerEntityInteraction(EntityKeys.BEE, (player, entity, item) -> canFeed(entity, item)); + registerEntityInteraction(EntityKeys.FOX, (player, entity, item) -> canFeed(entity, item)); + registerEntityInteraction(EntityKeys.FROG, (player, entity, item) -> canFeed(entity, item)); + registerEntityInteraction(EntityKeys.PANDA, (player, entity, item) -> canFeed(entity, item)); + registerEntityInteraction(EntityKeys.HOGLIN, (player, entity, item) -> canFeed(entity, item)); + registerEntityInteraction(EntityKeys.OCELOT, (player, entity, item) -> canFeed(entity, item)); + registerEntityInteraction(EntityKeys.RABBIT, (player, entity, item) -> canFeed(entity, item)); + registerEntityInteraction(EntityKeys.TURTLE, (player, entity, item) -> canFeed(entity, item)); + registerEntityInteraction(EntityKeys.CHICKEN, (player, entity, item) -> canFeed(entity, item)); + registerEntityInteraction(EntityKeys.SNIFFER, (player, entity, item) -> canFeed(entity, item)); + registerEntityInteraction(EntityKeys.AXOLOTL, (player, entity, item) -> + canFeed(entity, item) || (item != null && item.vanillaId().equals(ItemKeys.WATER_BUCKET))); + registerEntityInteraction(EntityKeys.COD, (player, entity, item) -> + item != null && item.vanillaId().equals(ItemKeys.WATER_BUCKET)); + registerEntityInteraction(EntityKeys.SALMON, (player, entity, item) -> + item != null && item.vanillaId().equals(ItemKeys.WATER_BUCKET)); + registerEntityInteraction(EntityKeys.TROPICAL_FISH, (player, entity, item) -> + item != null && item.vanillaId().equals(ItemKeys.WATER_BUCKET)); + registerEntityInteraction(EntityKeys.PUFFERFISH, (player, entity, item) -> + item != null && item.vanillaId().equals(ItemKeys.WATER_BUCKET)); + registerEntityInteraction(EntityKeys.TADPOLE, (player, entity, item) -> + item != null && item.vanillaId().equals(ItemKeys.WATER_BUCKET)); + registerEntityInteraction(EntityKeys.SNOW_GOLEM, (player, entity, item) -> shearable(entity, item)); + registerEntityInteraction(EntityKeys.SHEEP, (player, entity, item) -> canFeed(entity, item) || shearable(entity, item)); + registerEntityInteraction(EntityKeys.BOGGED, (player, entity, item) -> canFeed(entity, item) || shearable(entity, item)); + registerEntityInteraction(EntityKeys.MOOSHROOM, (player, entity, item) -> + canFeed(entity, item) || shearable(entity, item) || (item != null && (item.vanillaId().equals(ItemKeys.BUCKET) || item.vanillaId().equals(ItemKeys.BOWL)))); + registerEntityInteraction(EntityKeys.COW, (player, entity, item) -> + canFeed(entity, item) || (item != null && item.vanillaId().equals(ItemKeys.BUCKET))); + registerEntityInteraction(EntityKeys.GOAT, (player, entity, item) -> + canFeed(entity, item) || (item != null && item.vanillaId().equals(ItemKeys.BUCKET))); + registerEntityInteraction(EntityKeys.CREEPER, (player, entity, item) -> + item != null && item.vanillaId().equals(ItemKeys.FLINT_AND_STEEL)); + registerEntityInteraction(EntityKeys.PIGLIN, (player, entity, item) -> + item != null && item.vanillaId().equals(ItemKeys.GOLD_INGOT)); + registerEntityInteraction(EntityKeys.ARMADILLO, (player, entity, item) -> + canFeed(entity, item) || (item != null && item.vanillaId().equals(ItemKeys.BRUSH))); + registerEntityInteraction(EntityKeys.ZOMBIE_HORSE, (player, entity, item) -> + entity instanceof Tameable tameable && tameable.isTamed()); + registerEntityInteraction(EntityKeys.SKELETON_HORSE, (player, entity, item) -> + entity instanceof Tameable tameable && tameable.isTamed()); + registerEntityInteraction(EntityKeys.PIG, (player, entity, item) -> + canFeed(entity, item) || (hasSaddle(player, entity) && !player.isSneaking())); + registerEntityInteraction(EntityKeys.STRIDER, (player, entity, item) -> + canFeed(entity, item) || (hasSaddle(player, entity) && !player.isSneaking())); + registerEntityInteraction(EntityKeys.WOLF, (player, entity, item) -> canFeed(entity, item) || isPetOwner(player, entity)); + registerEntityInteraction(EntityKeys.CAT, (player, entity, item) -> canFeed(entity, item) || isPetOwner(player, entity)); registerEntityInteraction(EntityKeys.ACACIA_BOAT, (player, entity, item) -> !player.isSneaking()); registerEntityInteraction(EntityKeys.BAMBOO_BOAT, (player, entity, item) -> !player.isSneaking()); registerEntityInteraction(EntityKeys.BIRCH_BOAT, (player, entity, item) -> !player.isSneaking()); @@ -299,19 +349,21 @@ public class InteractUtils { registerEntityInteraction(EntityKeys.OAK_BOAT, (player, entity, item) -> !player.isSneaking()); registerEntityInteraction(EntityKeys.SPRUCE_BOAT, (player, entity, item) -> !player.isSneaking()); registerEntityInteraction(EntityKeys.MINECART, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityKeys.PARROT, (player, entity, item) -> { + if (item != null && item.is(Key.of("parrot_poisonous_food"))) return true; + return canFeed(entity, item) || isPetOwner(player, entity); + }); registerEntityInteraction(EntityKeys.HAPPY_GHAST, (player, entity, item) -> { if (!VersionHelper.isOrAbove1_21_6()) return false; - if (entity instanceof HappyGhast happyGhast) { + if (entity instanceof HappyGhast happyGhast && !player.isSneaking()) { ItemStack bodyItem = happyGhast.getEquipment().getItem(EquipmentSlot.BODY); - Item wrapped = BukkitItemManager.instance().wrap(bodyItem); - return wrapped.is(Key.of("harnesses")); + Item wrap = BukkitItemManager.instance().wrap(bodyItem); + return wrap.is(Key.of("harnesses")); } - return false; + return canFeed(entity, item); }); registerEntityInteraction(EntityKeys.ALLAY, (player, entity, item) -> true); registerEntityInteraction(EntityKeys.HORSE, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.ZOMBIE_HORSE, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.SKELETON_HORSE, (player, entity, item) -> true); registerEntityInteraction(EntityKeys.DONKEY, (player, entity, item) -> true); registerEntityInteraction(EntityKeys.MULE, (player, entity, item) -> true); registerEntityInteraction(EntityKeys.VILLAGER, (player, entity, item) -> true); @@ -392,11 +444,19 @@ public class InteractUtils { return ignoreHunger || player.isInvulnerable() || player.getFoodLevel() < 20; } - public static boolean hasSaddle(Player player, Entity entity) { + private static boolean canFeed(Entity entity, Item item) { + return entity instanceof Animals animals && item.is(Key.of(animals.getType().toString().toLowerCase() + "_food")); + } + + private static boolean hasSaddle(Player player, Entity entity) { return entity instanceof Steerable steerable && steerable.hasSaddle() && !player.isSneaking(); } - public static boolean isPetOwner(Player player, Entity entity) { + private static boolean shearable(Entity entity, Item item) { + return entity instanceof Shearable shearable && item.vanillaId().equals(ItemKeys.SHEARS) && shearable.readyToBeSheared(); + } + + private static boolean isPetOwner(Player player, Entity entity) { return entity instanceof Tameable tameable && tameable.isTamed() && player.getUniqueId().equals(tameable.getOwnerUniqueId()); } } 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 4e377f7d2..9da2f4f3f 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 @@ -41,10 +41,22 @@ public final class BlockKeys { 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"); + public static final Key JIGSAW = Key.of("minecraft:jigsaw"); + public static final Key STRUCTURE_BLOCK = Key.of("minecraft:structure_block"); + 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 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 CAKE = Key.of("minecraft:cake"); public static final Key CANDLE_CAKE = Key.of("minecraft:candle_cake"); @@ -161,6 +173,8 @@ public final class BlockKeys { 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 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"); diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/EntityKeys.java b/core/src/main/java/net/momirealms/craftengine/core/entity/EntityKeys.java index 6f075e3d6..721302092 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/EntityKeys.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/EntityKeys.java @@ -5,6 +5,29 @@ import net.momirealms.craftengine.core.util.Key; public class EntityKeys { private EntityKeys() {} + public static final Key BEE = Key.of("minecraft:BEE"); + public static final Key FOX = Key.of("minecraft:FOX"); + public static final Key FROG = Key.of("minecraft:FROG"); + public static final Key PANDA = Key.of("minecraft:PANDA"); + public static final Key SHEEP = Key.of("minecraft:SHEEP"); + public static final Key BOGGED = Key.of("minecraft:BOGGED"); + public static final Key SNOW_GOLEM = Key.of("minecraft:SNOW_GOLEM"); + public static final Key HOGLIN = Key.of("minecraft:HOGLIN"); + public static final Key OCELOT = Key.of("minecraft:OCELOT"); + public static final Key RABBIT = Key.of("minecraft:RABBIT"); + public static final Key TURTLE = Key.of("minecraft:TURTLE"); + public static final Key AXOLOTL = Key.of("minecraft:AXOLOTL"); + public static final Key CHICKEN = Key.of("minecraft:CHICKEN"); + public static final Key SNIFFER = Key.of("minecraft:SNIFFER"); + public static final Key ARMADILLO = Key.of("minecraft:ARMADILLO"); + public static final Key COD = Key.of("minecraft:COD"); + public static final Key SALMON = Key.of("minecraft:SALMON"); + public static final Key TROPICAL_FISH = Key.of("minecraft:TROPICAL_FISH"); + public static final Key PUFFERFISH = Key.of("minecraft:PUFFERFISH"); + public static final Key TADPOLE = Key.of("minecraft:TADPOLE"); + public static final Key COW = Key.of("minecraft:COW"); + public static final Key MOOSHROOM = Key.of("minecraft:MOOSHROOM"); + public static final Key GOAT = Key.of("minecraft:GOAT"); public static final Key PIG = Key.of("minecraft:PIG"); public static final Key STRIDER = Key.of("minecraft:STRIDER"); public static final Key WOLF = Key.of("minecraft:WOLF"); @@ -22,6 +45,7 @@ public class EntityKeys { public static final Key MINECART = Key.of("minecraft:MINECART"); public static final Key HAPPY_GHAST = Key.of("minecraft:HAPPY_GHAST"); public static final Key PIGLIN = Key.of("minecraft:PIGLIN"); + public static final Key CREEPER = Key.of("minecraft:CREEPER"); public static final Key ALLAY = Key.of("minecraft:ALLAY"); public static final Key HORSE = Key.of("minecraft:HORSE"); public static final Key ZOMBIE_HORSE = Key.of("minecraft:ZOMBIE_HORSE"); 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 7fc6b799a..148b73bb3 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 @@ -26,6 +26,7 @@ public class ItemKeys { public static final Key TROPICAL_FISH_BUCKET = Key.of("minecraft:tropical_fish_bucket"); public static final Key PUFFERFISH_BUCKET = Key.of("minecraft:pufferfish_bucket"); public static final Key AXOLOTL_BUCKET = Key.of("minecraft:axolotl_bucket"); + public static final Key LAVA_BUCKET = Key.of("minecraft:lava_bucket"); public static final Key BUCKET = Key.of("minecraft:bucket"); public static final Key BONE_MEAL = Key.of("minecraft:bone_meal"); public static final Key ENCHANTED_BOOK = Key.of("minecraft:enchanted_book"); @@ -34,6 +35,10 @@ public class ItemKeys { public static final Key CACTUS = Key.of("minecraft:cactus"); public static final Key REDSTONE = Key.of("minecraft:redstone"); public static final Key GOLD_INGOT = Key.of("minecraft:gold_ingot"); + public static final Key SHEARS = Key.of("minecraft:shears"); + public static final Key BRUSH = Key.of("minecraft:brush"); + public static final Key BOWL = Key.of("minecraft:bowl"); + public static final Key GLASS_BOTTLE = Key.of("minecraft:glass_bottle"); public static final Key[] AXES = new Key[] { WOODEN_AXE, STONE_AXE, IRON_AXE, GOLDEN_AXE, DIAMOND_AXE, NETHERITE_AXE From 821a11b4780eeefdd7cfa2476ed58bb40219e44d Mon Sep 17 00:00:00 2001 From: halogly Date: Sat, 26 Jul 2025 00:25:09 +0800 Subject: [PATCH 16/16] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E6=96=B9=E5=9D=97=E7=9A=84=E5=88=A4=E6=96=AD=E9=80=BB=E8=BE=91?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=E4=BA=A4=E4=BA=92=E6=96=B9=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/util/InteractUtils.java | 211 +++++++++++------- .../craftengine/core/block/BlockKeys.java | 3 + .../{EntityKeys.java => EntityTypeKeys.java} | 4 +- .../craftengine/core/item/ItemKeys.java | 3 + 4 files changed, 134 insertions(+), 87 deletions(-) rename core/src/main/java/net/momirealms/craftengine/core/entity/{EntityKeys.java => EntityTypeKeys.java} (98%) 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 39cbba3da..e610903df 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 @@ -2,11 +2,13 @@ package net.momirealms.craftengine.bukkit.util; 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.core.block.BlockKeys; -import net.momirealms.craftengine.core.entity.EntityKeys; +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.recipe.RecipeTypes; import net.momirealms.craftengine.core.item.recipe.UniqueIdItem; import net.momirealms.craftengine.core.item.recipe.input.SingleItemInput; @@ -15,9 +17,12 @@ import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.util.*; import net.momirealms.craftengine.core.world.BlockHitResult; import net.momirealms.craftengine.core.world.BlockPos; +import org.bukkit.GameMode; 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.entity.*; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; @@ -53,9 +58,43 @@ public class InteractUtils { 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.BEE_NEST, (player, item, blockState, result) -> item.vanillaId().equals(ItemKeys.SHEARS) || item.vanillaId().equals(ItemKeys.GLASS_BOTTLE)); - registerInteraction(BlockKeys.BEEHIVE, (player, item, blockState, result) -> item.vanillaId().equals(ItemKeys.SHEARS) || item.vanillaId().equals(ItemKeys.GLASS_BOTTLE)); + 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) -> Set.of(ItemKeys.SHEARS, ItemKeys.GLASS_BOTTLE).contains(item.vanillaId())); + registerInteraction(BlockKeys.BEEHIVE, (player, item, blockState, result) -> Set.of(ItemKeys.SHEARS, ItemKeys.GLASS_BOTTLE).contains(item.vanillaId())); registerInteraction(BlockKeys.POWDER_SNOW, (player, item, blockState, result) -> item.vanillaId().equals(ItemKeys.BUCKET)); + registerWillConsume(BlockKeys.CAULDRON, (player, item, blockState, result) -> Set.of(ItemKeys.WATER_BUCKET, ItemKeys.LAVA_BUCKET).contains(item.vanillaId())); + registerWillConsume(BlockKeys.LAVA_CAULDRON, (player, item, blockState, result) -> Set.of(ItemKeys.BUCKET, ItemKeys.WATER_BUCKET, ItemKeys.LAVA_BUCKET).contains(item.vanillaId())); + 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; + }); + registerWillConsume(BlockKeys.WATER_CAULDRON, (player, item, blockState, result) -> { + if (blockState instanceof Levelled levelled && levelled.getLevel() == levelled.getMaximumLevel()) + return item.vanillaId().equals(ItemKeys.BUCKET); + return Set.of(ItemKeys.GLASS_BOTTLE, ItemKeys.WATER_BUCKET, ItemKeys.LAVA_BUCKET).contains(item.vanillaId()); + }); registerInteraction(BlockKeys.BELL, (player, item, blockState, result) -> { Direction direction = result.getDirection(); BlockPos pos = result.getBlockPos(); @@ -98,7 +137,16 @@ public class InteractUtils { 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.RESPAWN_ANCHOR, (player, item, blockState, result) -> { + if (item.vanillaId().equals(ItemKeys.GLOWSTONE)) 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.DISPENSER, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.DROPPER, (player, item, blockState, result) -> true); @@ -274,16 +322,6 @@ public class InteractUtils { 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); - registerInteraction(BlockKeys.COMMAND_BLOCK, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.CHAIN_COMMAND_BLOCK, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.REPEATING_COMMAND_BLOCK, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.JIGSAW, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.STRUCTURE_BLOCK, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.TEST_INSTANCE_BLOCK, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.TEST_BLOCK, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.LIGHT, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.REDSTONE_ORE, (player, item, blockState, result) -> true); - registerInteraction(BlockKeys.DEEPSLATE_REDSTONE_ORE, (player, item, blockState, result) -> true); } static { @@ -292,68 +330,71 @@ public class InteractUtils { } static { - registerEntityInteraction(EntityKeys.BEE, (player, entity, item) -> canFeed(entity, item)); - registerEntityInteraction(EntityKeys.FOX, (player, entity, item) -> canFeed(entity, item)); - registerEntityInteraction(EntityKeys.FROG, (player, entity, item) -> canFeed(entity, item)); - registerEntityInteraction(EntityKeys.PANDA, (player, entity, item) -> canFeed(entity, item)); - registerEntityInteraction(EntityKeys.HOGLIN, (player, entity, item) -> canFeed(entity, item)); - registerEntityInteraction(EntityKeys.OCELOT, (player, entity, item) -> canFeed(entity, item)); - registerEntityInteraction(EntityKeys.RABBIT, (player, entity, item) -> canFeed(entity, item)); - registerEntityInteraction(EntityKeys.TURTLE, (player, entity, item) -> canFeed(entity, item)); - registerEntityInteraction(EntityKeys.CHICKEN, (player, entity, item) -> canFeed(entity, item)); - registerEntityInteraction(EntityKeys.SNIFFER, (player, entity, item) -> canFeed(entity, item)); - registerEntityInteraction(EntityKeys.AXOLOTL, (player, entity, item) -> + 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(EntityKeys.COD, (player, entity, item) -> + registerEntityInteraction(EntityTypeKeys.COD, (player, entity, item) -> item != null && item.vanillaId().equals(ItemKeys.WATER_BUCKET)); - registerEntityInteraction(EntityKeys.SALMON, (player, entity, item) -> + registerEntityInteraction(EntityTypeKeys.SALMON, (player, entity, item) -> item != null && item.vanillaId().equals(ItemKeys.WATER_BUCKET)); - registerEntityInteraction(EntityKeys.TROPICAL_FISH, (player, entity, item) -> + registerEntityInteraction(EntityTypeKeys.TROPICAL_FISH, (player, entity, item) -> item != null && item.vanillaId().equals(ItemKeys.WATER_BUCKET)); - registerEntityInteraction(EntityKeys.PUFFERFISH, (player, entity, item) -> + registerEntityInteraction(EntityTypeKeys.PUFFERFISH, (player, entity, item) -> item != null && item.vanillaId().equals(ItemKeys.WATER_BUCKET)); - registerEntityInteraction(EntityKeys.TADPOLE, (player, entity, item) -> + registerEntityInteraction(EntityTypeKeys.TADPOLE, (player, entity, item) -> item != null && item.vanillaId().equals(ItemKeys.WATER_BUCKET)); - registerEntityInteraction(EntityKeys.SNOW_GOLEM, (player, entity, item) -> shearable(entity, item)); - registerEntityInteraction(EntityKeys.SHEEP, (player, entity, item) -> canFeed(entity, item) || shearable(entity, item)); - registerEntityInteraction(EntityKeys.BOGGED, (player, entity, item) -> canFeed(entity, item) || shearable(entity, item)); - registerEntityInteraction(EntityKeys.MOOSHROOM, (player, entity, item) -> + 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(EntityKeys.COW, (player, entity, item) -> + registerEntityInteraction(EntityTypeKeys.COW, (player, entity, item) -> canFeed(entity, item) || (item != null && item.vanillaId().equals(ItemKeys.BUCKET))); - registerEntityInteraction(EntityKeys.GOAT, (player, entity, item) -> + registerEntityInteraction(EntityTypeKeys.GOAT, (player, entity, item) -> canFeed(entity, item) || (item != null && item.vanillaId().equals(ItemKeys.BUCKET))); - registerEntityInteraction(EntityKeys.CREEPER, (player, entity, item) -> + registerEntityInteraction(EntityTypeKeys.CREEPER, (player, entity, item) -> item != null && item.vanillaId().equals(ItemKeys.FLINT_AND_STEEL)); - registerEntityInteraction(EntityKeys.PIGLIN, (player, entity, item) -> + registerEntityInteraction(EntityTypeKeys.PIGLIN, (player, entity, item) -> item != null && item.vanillaId().equals(ItemKeys.GOLD_INGOT)); - registerEntityInteraction(EntityKeys.ARMADILLO, (player, entity, item) -> + registerEntityInteraction(EntityTypeKeys.ARMADILLO, (player, entity, item) -> canFeed(entity, item) || (item != null && item.vanillaId().equals(ItemKeys.BRUSH))); - registerEntityInteraction(EntityKeys.ZOMBIE_HORSE, (player, entity, item) -> + registerEntityInteraction(EntityTypeKeys.ZOMBIE_HORSE, (player, entity, item) -> entity instanceof Tameable tameable && tameable.isTamed()); - registerEntityInteraction(EntityKeys.SKELETON_HORSE, (player, entity, item) -> + registerEntityInteraction(EntityTypeKeys.SKELETON_HORSE, (player, entity, item) -> entity instanceof Tameable tameable && tameable.isTamed()); - registerEntityInteraction(EntityKeys.PIG, (player, entity, item) -> + registerEntityInteraction(EntityTypeKeys.PIG, (player, entity, item) -> canFeed(entity, item) || (hasSaddle(player, entity) && !player.isSneaking())); - registerEntityInteraction(EntityKeys.STRIDER, (player, entity, item) -> + registerEntityInteraction(EntityTypeKeys.STRIDER, (player, entity, item) -> canFeed(entity, item) || (hasSaddle(player, entity) && !player.isSneaking())); - registerEntityInteraction(EntityKeys.WOLF, (player, entity, item) -> canFeed(entity, item) || isPetOwner(player, entity)); - registerEntityInteraction(EntityKeys.CAT, (player, entity, item) -> canFeed(entity, item) || isPetOwner(player, entity)); - registerEntityInteraction(EntityKeys.ACACIA_BOAT, (player, entity, item) -> !player.isSneaking()); - registerEntityInteraction(EntityKeys.BAMBOO_BOAT, (player, entity, item) -> !player.isSneaking()); - registerEntityInteraction(EntityKeys.BIRCH_BOAT, (player, entity, item) -> !player.isSneaking()); - registerEntityInteraction(EntityKeys.CHERRY_BOAT, (player, entity, item) -> !player.isSneaking()); - registerEntityInteraction(EntityKeys.DARK_OAK_BOAT, (player, entity, item) -> !player.isSneaking()); - registerEntityInteraction(EntityKeys.JUNGLE_BOAT, (player, entity, item) -> !player.isSneaking()); - registerEntityInteraction(EntityKeys.MANGROVE_BOAT, (player, entity, item) -> !player.isSneaking()); - registerEntityInteraction(EntityKeys.OAK_BOAT, (player, entity, item) -> !player.isSneaking()); - registerEntityInteraction(EntityKeys.SPRUCE_BOAT, (player, entity, item) -> !player.isSneaking()); - registerEntityInteraction(EntityKeys.MINECART, (player, entity, item) -> !player.isSneaking()); - registerEntityInteraction(EntityKeys.PARROT, (player, entity, item) -> { + registerEntityInteraction(EntityTypeKeys.WOLF, (player, entity, item) -> canFeed(entity, item) || isPetOwner(player, entity)); + registerEntityInteraction(EntityTypeKeys.CAT, (player, entity, item) -> canFeed(entity, item) || isPetOwner(player, entity)); + registerEntityInteraction(EntityTypeKeys.ACACIA_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityTypeKeys.BAMBOO_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityTypeKeys.BIRCH_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityTypeKeys.CHERRY_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityTypeKeys.DARK_OAK_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityTypeKeys.JUNGLE_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityTypeKeys.MANGROVE_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityTypeKeys.OAK_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityTypeKeys.SPRUCE_BOAT, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityTypeKeys.MINECART, (player, entity, item) -> !player.isSneaking()); + registerEntityInteraction(EntityTypeKeys.PARROT, (player, entity, item) -> { if (item != null && item.is(Key.of("parrot_poisonous_food"))) return true; return canFeed(entity, item) || isPetOwner(player, entity); }); - registerEntityInteraction(EntityKeys.HAPPY_GHAST, (player, entity, item) -> { + registerEntityInteraction(EntityTypeKeys.HAPPY_GHAST, (player, entity, item) -> { if (!VersionHelper.isOrAbove1_21_6()) return false; if (entity instanceof HappyGhast happyGhast && !player.isSneaking()) { ItemStack bodyItem = happyGhast.getEquipment().getItem(EquipmentSlot.BODY); @@ -362,36 +403,36 @@ public class InteractUtils { } return canFeed(entity, item); }); - registerEntityInteraction(EntityKeys.ALLAY, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.HORSE, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.DONKEY, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.MULE, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.VILLAGER, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.WANDERING_TRADER, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.LLAMA, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.TRADER_LLAMA, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.CAMEL, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.ITEM_FRAME, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.GLOW_ITEM_FRAME, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.INTERACTION, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.ACACIA_CHEST_BOAT, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.BAMBOO_CHEST_BOAT, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.BIRCH_CHEST_BOAT, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.CHERRY_CHEST_BOAT, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.DARK_OAK_CHEST_BOAT, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.JUNGLE_CHEST_BOAT, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.MANGROVE_CHEST_BOAT, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.OAK_CHEST_BOAT, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.SPRUCE_CHEST_BOAT, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.CHEST_MINECART, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.FURNACE_MINECART, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.HOPPER_MINECART, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.COMMAND_BLOCK_MINECART, (player, entity, item) -> true); + 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.ACACIA_CHEST_BOAT, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.BAMBOO_CHEST_BOAT, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.BIRCH_CHEST_BOAT, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.CHERRY_CHEST_BOAT, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.DARK_OAK_CHEST_BOAT, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.JUNGLE_CHEST_BOAT, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.MANGROVE_CHEST_BOAT, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.OAK_CHEST_BOAT, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.SPRUCE_CHEST_BOAT, (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); //<1.20.5 - registerEntityInteraction(EntityKeys.MINECART_CHEST, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.MINECART_HOPPER, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.MINECART_FURNACE, (player, entity, item) -> true); - registerEntityInteraction(EntityKeys.MINECART_COMMAND, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.MINECART_CHEST, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.MINECART_HOPPER, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.MINECART_FURNACE, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.MINECART_COMMAND, (player, entity, item) -> true); } private static void registerInteraction(Key key, QuadFunction, BlockData, BlockHitResult, Boolean> function) { 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 9da2f4f3f..6f5daecc9 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 @@ -47,6 +47,7 @@ public final class BlockKeys { 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"); @@ -57,6 +58,8 @@ public final class BlockKeys { 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 CAKE = Key.of("minecraft:cake"); public static final Key CANDLE_CAKE = Key.of("minecraft:candle_cake"); diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/EntityKeys.java b/core/src/main/java/net/momirealms/craftengine/core/entity/EntityTypeKeys.java similarity index 98% rename from core/src/main/java/net/momirealms/craftengine/core/entity/EntityKeys.java rename to core/src/main/java/net/momirealms/craftengine/core/entity/EntityTypeKeys.java index 721302092..55b71f54a 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/EntityKeys.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/EntityTypeKeys.java @@ -2,8 +2,8 @@ package net.momirealms.craftengine.core.entity; import net.momirealms.craftengine.core.util.Key; -public class EntityKeys { - private EntityKeys() {} +public class EntityTypeKeys { + private EntityTypeKeys() {} public static final Key BEE = Key.of("minecraft:BEE"); public static final Key FOX = Key.of("minecraft:FOX"); 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 148b73bb3..f49121f0d 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 @@ -38,7 +38,10 @@ public class ItemKeys { public static final Key SHEARS = Key.of("minecraft:shears"); public static final Key BRUSH = Key.of("minecraft:brush"); public static final Key BOWL = Key.of("minecraft:bowl"); + public static final Key COMPASS = Key.of("minecraft:compass"); public static final Key GLASS_BOTTLE = Key.of("minecraft:glass_bottle"); + public static final Key LIGHT = Key.of("minecraft:light"); + public static final Key GLOWSTONE = Key.of("minecraft:glowstone"); public static final Key[] AXES = new Key[] { WOODEN_AXE, STONE_AXE, IRON_AXE, GOLDEN_AXE, DIAMOND_AXE, NETHERITE_AXE