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 ee42c4648..73471279c 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,7 +67,9 @@ public class ItemEventListener implements Listener { @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) public void onInteractEntity(PlayerInteractEntityEvent event) { - BukkitServerPlayer serverPlayer = this.plugin.adapt(event.getPlayer()); + Player player = event.getPlayer(); + Entity entity = event.getRightClicked(); + 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); @@ -74,6 +77,7 @@ 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; Cancellable cancellable = Cancellable.of(event::isCancelled, event::setCancelled); PlayerOptionalContext context = PlayerOptionalContext.of(serverPlayer, ContextHolder.builder() @@ -275,7 +279,9 @@ public class ItemEventListener implements Listener { .withParameter(DirectContextParameters.EVENT, dummy) ); CustomItem customItem = optionalCustomItem.get(); - customItem.execute(context, EventTrigger.RIGHT_CLICK); + if (!(InteractUtils.isInteractable(player, blockData, hitResult, itemInHand) && !player.isSneaking())) { + 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/EntityUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java index 30fd6fa4b..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 @@ -6,16 +6,15 @@ 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 java.util.function.Consumer; public class EntityUtils { - private EntityUtils() {} + private EntityUtils() { + } public static BlockPos getOnPos(Player player) { try { @@ -34,4 +33,4 @@ public class EntityUtils { return LegacyEntityUtils.spawnEntity(world, loc, type, function); } } -} +} \ 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 11f5213b8..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 @@ -1,31 +1,39 @@ 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.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; 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.*; 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.entity.Player; +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; import org.jetbrains.annotations.Nullable; -import java.util.HashMap; -import java.util.Map; +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 Map, Boolean>> ENTITY_INTERACTIONS = new HashMap<>(); private static final Key NOTE_BLOCK_TOP_INSTRUMENTS = Key.of("minecraft:noteblock_top_instruments"); private InteractUtils() {} @@ -50,6 +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.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(); @@ -88,7 +133,20 @@ public class InteractUtils { item.recipeIngredientId(), item ))) != null; }); + registerInteraction(BlockKeys.CHISELED_BOOKSHELF, (player, item, blockState, result) -> { + if (!(blockState instanceof ChiseledBookshelf chiseledBookshelf)) return false; + return DirectionUtils.toDirection(chiseledBookshelf.getFacing()) == result.getDirection(); + }); + registerInteraction(BlockKeys.COMPOSTER, (player, item, blockState, result) -> { + if (item.getItem().getType().isCompostable()) return true; + return blockState instanceof Levelled levelled && levelled.getLevel() == levelled.getMaximumLevel(); + }); + registerInteraction(BlockKeys.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); @@ -264,9 +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.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); } static { @@ -274,6 +329,112 @@ public class InteractUtils { result.getDirection() == Direction.UP && item.id().equals(ItemKeys.CACTUS)); } + static { + registerEntityInteraction(EntityTypeKeys.BEE, (player, entity, item) -> canFeed(entity, item)); + registerEntityInteraction(EntityTypeKeys.FOX, (player, entity, item) -> canFeed(entity, item)); + registerEntityInteraction(EntityTypeKeys.FROG, (player, entity, item) -> canFeed(entity, item)); + registerEntityInteraction(EntityTypeKeys.PANDA, (player, entity, item) -> canFeed(entity, item)); + registerEntityInteraction(EntityTypeKeys.HOGLIN, (player, entity, item) -> canFeed(entity, item)); + registerEntityInteraction(EntityTypeKeys.OCELOT, (player, entity, item) -> canFeed(entity, item)); + registerEntityInteraction(EntityTypeKeys.RABBIT, (player, entity, item) -> canFeed(entity, item)); + registerEntityInteraction(EntityTypeKeys.TURTLE, (player, entity, item) -> canFeed(entity, item)); + registerEntityInteraction(EntityTypeKeys.CHICKEN, (player, entity, item) -> canFeed(entity, item)); + registerEntityInteraction(EntityTypeKeys.SNIFFER, (player, entity, item) -> canFeed(entity, item)); + registerEntityInteraction(EntityTypeKeys.AXOLOTL, (player, entity, item) -> + canFeed(entity, item) || (item != null && item.vanillaId().equals(ItemKeys.WATER_BUCKET))); + registerEntityInteraction(EntityTypeKeys.COD, (player, entity, item) -> + item != null && item.vanillaId().equals(ItemKeys.WATER_BUCKET)); + registerEntityInteraction(EntityTypeKeys.SALMON, (player, entity, item) -> + item != null && item.vanillaId().equals(ItemKeys.WATER_BUCKET)); + registerEntityInteraction(EntityTypeKeys.TROPICAL_FISH, (player, entity, item) -> + item != null && item.vanillaId().equals(ItemKeys.WATER_BUCKET)); + registerEntityInteraction(EntityTypeKeys.PUFFERFISH, (player, entity, item) -> + item != null && item.vanillaId().equals(ItemKeys.WATER_BUCKET)); + registerEntityInteraction(EntityTypeKeys.TADPOLE, (player, entity, item) -> + item != null && item.vanillaId().equals(ItemKeys.WATER_BUCKET)); + registerEntityInteraction(EntityTypeKeys.SNOW_GOLEM, (player, entity, item) -> + shearable(entity, item)); + registerEntityInteraction(EntityTypeKeys.SHEEP, (player, entity, item) -> + canFeed(entity, item) || shearable(entity, item)); + registerEntityInteraction(EntityTypeKeys.BOGGED, (player, entity, item) -> + canFeed(entity, item) || shearable(entity, item)); + registerEntityInteraction(EntityTypeKeys.MOOSHROOM, (player, entity, item) -> + canFeed(entity, item) || shearable(entity, item) || (item != null && (item.vanillaId().equals(ItemKeys.BUCKET) || item.vanillaId().equals(ItemKeys.BOWL)))); + registerEntityInteraction(EntityTypeKeys.COW, (player, entity, item) -> + canFeed(entity, item) || (item != null && item.vanillaId().equals(ItemKeys.BUCKET))); + registerEntityInteraction(EntityTypeKeys.GOAT, (player, entity, item) -> + canFeed(entity, item) || (item != null && item.vanillaId().equals(ItemKeys.BUCKET))); + registerEntityInteraction(EntityTypeKeys.CREEPER, (player, entity, item) -> + item != null && item.vanillaId().equals(ItemKeys.FLINT_AND_STEEL)); + registerEntityInteraction(EntityTypeKeys.PIGLIN, (player, entity, item) -> + item != null && item.vanillaId().equals(ItemKeys.GOLD_INGOT)); + registerEntityInteraction(EntityTypeKeys.ARMADILLO, (player, entity, item) -> + canFeed(entity, item) || (item != null && item.vanillaId().equals(ItemKeys.BRUSH))); + registerEntityInteraction(EntityTypeKeys.ZOMBIE_HORSE, (player, entity, item) -> + entity instanceof Tameable tameable && tameable.isTamed()); + registerEntityInteraction(EntityTypeKeys.SKELETON_HORSE, (player, entity, item) -> + entity instanceof Tameable tameable && tameable.isTamed()); + registerEntityInteraction(EntityTypeKeys.PIG, (player, entity, item) -> + canFeed(entity, item) || (hasSaddle(player, entity) && !player.isSneaking())); + registerEntityInteraction(EntityTypeKeys.STRIDER, (player, entity, item) -> + canFeed(entity, item) || (hasSaddle(player, entity) && !player.isSneaking())); + registerEntityInteraction(EntityTypeKeys.WOLF, (player, entity, item) -> canFeed(entity, item) || isPetOwner(player, entity)); + registerEntityInteraction(EntityTypeKeys.CAT, (player, entity, item) -> canFeed(entity, item) || isPetOwner(player, entity)); + 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(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); + Item wrap = BukkitItemManager.instance().wrap(bodyItem); + return wrap.is(Key.of("harnesses")); + } + return canFeed(entity, item); + }); + registerEntityInteraction(EntityTypeKeys.ALLAY, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.HORSE, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.DONKEY, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.MULE, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.VILLAGER, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.WANDERING_TRADER, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.LLAMA, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.TRADER_LLAMA, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.CAMEL, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.ITEM_FRAME, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.GLOW_ITEM_FRAME, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.INTERACTION, (player, entity, item) -> true); + registerEntityInteraction(EntityTypeKeys.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(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) { var previous = INTERACTIONS.put(key, function); if (previous != null) { @@ -288,6 +449,13 @@ public class InteractUtils { } } + 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); + } + } + public static boolean isInteractable(Player player, BlockData state, BlockHitResult hit, @Nullable Item item) { Key blockType = BlockStateUtils.getBlockOwnerIdFromData(state); if (INTERACTIONS.containsKey(blockType)) { @@ -297,6 +465,12 @@ public class InteractUtils { } } + 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) { if (item == null) return false; Key blockType = BlockStateUtils.getBlockOwnerIdFromData(state); @@ -306,8 +480,24 @@ public class InteractUtils { return false; } } - + private static boolean canEat(Player player, boolean ignoreHunger) { return ignoreHunger || player.isInvulnerable() || player.getFoodLevel() < 20; } + + 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(); + } + + 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/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..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 @@ -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; 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..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 @@ -41,7 +41,25 @@ 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 FLOWER_POT = Key.of("minecraft:flower_pot"); + public static final Key CHISELED_BOOKSHELF = Key.of("minecraft:chiseled_bookshelf"); + public static final Key REDSTONE_ORE = Key.of("minecraft:redstone_ore"); + public static final Key DEEPSLATE_REDSTONE_ORE = Key.of("minecraft:deepslate_redstone_ore"); + public static final Key BEE_NEST = Key.of("minecraft:bee_nest"); + public static final Key BEEHIVE = Key.of("minecraft:beehive"); + public static final Key POWDER_SNOW = Key.of("minecraft:powder_snow"); + public static final Key COMPOSTER = Key.of("minecraft:composter"); + public static final Key CAULDRON = Key.of("minecraft:cauldron"); + public static final Key WATER_CAULDRON = Key.of("minecraft:water_cauldron"); + public static final Key LAVA_CAULDRON = Key.of("minecraft:lava_cauldron"); + public static final Key RESPAWN_ANCHOR = Key.of("minecraft:respawn_anchor"); + public static final Key LODESTONE = Key.of("minecraft:lodestone"); public static final Key CAKE = Key.of("minecraft:cake"); public static final Key CANDLE_CAKE = Key.of("minecraft:candle_cake"); @@ -158,6 +176,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/EntityTypeKeys.java b/core/src/main/java/net/momirealms/craftengine/core/entity/EntityTypeKeys.java new file mode 100644 index 000000000..55b71f54a --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/EntityTypeKeys.java @@ -0,0 +1,81 @@ +package net.momirealms.craftengine.core.entity; + +import net.momirealms.craftengine.core.util.Key; + +public class EntityTypeKeys { + private EntityTypeKeys() {} + + 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"); + 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 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"); + 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"); + 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 + 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"); +} 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..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 @@ -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"); @@ -33,6 +34,14 @@ 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 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