diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BucketItemBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BucketItemBehavior.java index 650982dfe..cefc0255b 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BucketItemBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BucketItemBehavior.java @@ -1,10 +1,10 @@ package net.momirealms.craftengine.bukkit.item.behavior; -import net.momirealms.craftengine.bukkit.api.CraftEngineBlocks; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; +import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.util.BlockStateUtils; -import net.momirealms.craftengine.bukkit.world.BukkitBlockInWorld; +import net.momirealms.craftengine.bukkit.util.LocationUtils; import net.momirealms.craftengine.core.block.CustomBlock; import net.momirealms.craftengine.core.block.ImmutableBlockState; import net.momirealms.craftengine.core.block.UpdateOption; @@ -16,12 +16,16 @@ import net.momirealms.craftengine.core.item.behavior.ItemBehaviorFactory; import net.momirealms.craftengine.core.item.context.UseOnContext; import net.momirealms.craftengine.core.pack.Pack; import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.world.BlockPos; -import org.bukkit.*; +import org.bukkit.FluidCollisionMode; +import org.bukkit.Material; +import org.bukkit.Statistic; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; +import org.bukkit.util.RayTraceResult; import java.nio.file.Path; import java.util.Map; @@ -30,34 +34,49 @@ public class BucketItemBehavior extends ItemBehavior { public static final BucketItemBehavior INSTANCE = new BucketItemBehavior(); public static final Factory FACTORY = new Factory(); - // todo 需要修复点击位置相连块为waterlogged - @SuppressWarnings("unchecked") @Override public InteractionResult useOnBlock(UseOnContext context) { - if (context.getPlayer().isAdventureMode()) return InteractionResult.PASS; - BukkitBlockInWorld clicked = (BukkitBlockInWorld) context.getLevel().getBlockAt(context.getClickedPos()); - Block block = clicked.block(); - ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockDataToId(block.getBlockData())); - if (state == null || state.isEmpty()) return InteractionResult.PASS; - CustomBlock customBlock = state.owner().value(); + return use(context.getLevel(), context.getPlayer(), context.getHand()); + } + + @Override + public InteractionResult use(net.momirealms.craftengine.core.world.World world, net.momirealms.craftengine.core.entity.player.Player player, InteractionHand hand) { + if (player.isAdventureMode()) return InteractionResult.PASS; + Player bukkitPlayer = (Player) player.platformPlayer(); + RayTraceResult result = bukkitPlayer.rayTraceBlocks(player.getCachedInteractionRange(), FluidCollisionMode.SOURCE_ONLY); + if (result == null) return InteractionResult.PASS; + Block block = result.getHitBlock(); + if (block == null) return InteractionResult.PASS; + return tryFillBucket(world, player, hand, new BlockPos(block.getX(), block.getY(), block.getZ())); + } + + @SuppressWarnings("unchecked") + private InteractionResult tryFillBucket(net.momirealms.craftengine.core.world.World world, + net.momirealms.craftengine.core.entity.player.Player player, + InteractionHand hand, + BlockPos pos) { + Object nmsPos = LocationUtils.toBlockPos(pos.x(), pos.y(), pos.z()); + Object blockState = FastNMS.INSTANCE.method$BlockGetter$getBlockState(world.serverWorld(), nmsPos); + ImmutableBlockState customState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState)); + if (customState == null || customState.isEmpty()) return InteractionResult.PASS; + CustomBlock customBlock = customState.owner().value(); Property waterlogged = (Property) customBlock.getProperty("waterlogged"); if (waterlogged == null) return InteractionResult.PASS; - boolean waterloggedState = state.get(waterlogged); + boolean waterloggedState = customState.get(waterlogged); if (!waterloggedState) return InteractionResult.PASS; - BlockPos pos = context.getClickedPos(); - Player player = (Player) context.getPlayer().platformPlayer(); - World world = player.getWorld(); - Location location = new Location(world, pos.x(), pos.y(), pos.z()); - EquipmentSlot slot = context.getHand() == InteractionHand.MAIN_HAND ? EquipmentSlot.HAND : EquipmentSlot.OFF_HAND; - - CraftEngineBlocks.place(location, state.with(waterlogged, false), UpdateOption.UPDATE_ALL, false); - if (player.getGameMode() == GameMode.SURVIVAL) { + EquipmentSlot slot = hand == InteractionHand.MAIN_HAND ? EquipmentSlot.HAND : EquipmentSlot.OFF_HAND; + FastNMS.INSTANCE.method$LevelWriter$setBlock(world.serverWorld(), nmsPos, customState.with(waterlogged, false).customBlockState().handle(), UpdateOption.UPDATE_ALL.flags()); + Player bukkitPlayer = (Player) player.platformPlayer(); + if (player.isSurvivalMode()) { // to prevent dupe in moment - player.getInventory().setItem(slot, new ItemStack(Material.AIR)); - BukkitCraftEngine.instance().scheduler().sync().runDelayed(() -> - player.getInventory().setItem(slot, new ItemStack(Material.WATER_BUCKET)), world, location.getBlockX() >> 4, location.getBlockZ() >> 4); + bukkitPlayer.getInventory().setItem(slot, new ItemStack(Material.AIR)); + if (VersionHelper.isFolia()) { + bukkitPlayer.getScheduler().run(BukkitCraftEngine.instance().javaPlugin(), (t) -> bukkitPlayer.getInventory().setItem(slot, new ItemStack(Material.WATER_BUCKET)), () -> {}); + } else { + BukkitCraftEngine.instance().scheduler().sync().runDelayed(() -> bukkitPlayer.getInventory().setItem(slot, new ItemStack(Material.WATER_BUCKET))); + } } - player.setStatistic(Statistic.USE_ITEM, Material.BUCKET, player.getStatistic(Statistic.USE_ITEM, Material.BUCKET) + 1); + bukkitPlayer.setStatistic(Statistic.USE_ITEM, Material.BUCKET, bukkitPlayer.getStatistic(Statistic.USE_ITEM, Material.BUCKET) + 1); // client will assume it has sounds // context.getPlayer().level().playBlockSound(Vec3d.atCenterOf(context.getClickedPos()), ITEM_BUCKET_FILL, 1, 1); return InteractionResult.SUCCESS_AND_CANCEL; 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 1704d68a5..15570c1fd 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 @@ -299,7 +299,7 @@ public class ItemEventListener implements Listener { } } - @EventHandler + @EventHandler(priority = EventPriority.HIGH) public void onInteractAir(PlayerInteractEvent event) { Action action = event.getAction(); if (action != Action.RIGHT_CLICK_AIR && action != Action.LEFT_CLICK_AIR) @@ -315,9 +315,9 @@ public class ItemEventListener implements Listener { if (itemInHand == null) return; // todo 真的需要这个吗 -// if (cancelEventIfHasInteraction(event, serverPlayer, hand)) { -// return; -// } + if (cancelEventIfHasInteraction(event, serverPlayer, hand)) { + return; + } Optional> optionalCustomItem = itemInHand.getCustomItem(); if (optionalCustomItem.isPresent()) { @@ -336,6 +336,9 @@ public class ItemEventListener implements Listener { if (optionalItemBehaviors.isPresent()) { for (ItemBehavior itemBehavior : optionalItemBehaviors.get()) { InteractionResult result = itemBehavior.use(serverPlayer.world(), serverPlayer, hand); + if (result.success()) { + serverPlayer.updateLastSuccessfulInteractionTick(serverPlayer.gameTicks()); + } if (result == InteractionResult.SUCCESS_AND_CANCEL) { event.setCancelled(true); return; diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/data/ClassTreeIdRegistry.java b/core/src/main/java/net/momirealms/craftengine/core/entity/data/ClassTreeIdRegistry.java index 8d4f86d70..e5d77935b 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/data/ClassTreeIdRegistry.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/data/ClassTreeIdRegistry.java @@ -2,7 +2,6 @@ package net.momirealms.craftengine.core.entity.data; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; -import net.momirealms.craftengine.core.plugin.CraftEngine; public final class ClassTreeIdRegistry { private final Object2IntMap> classToLastIdCache = new Object2IntOpenHashMap<>(); diff --git a/gradle.properties b/gradle.properties index a9c37c7f5..a065f1c6c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.57.4 +project_version=0.0.57.5 config_version=37 lang_version=17 project_group=net.momirealms