9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-26 18:39:20 +00:00

修复空桶行为

This commit is contained in:
XiaoMoMi
2025-06-19 03:23:37 +08:00
parent 6490dd8bdc
commit 15104ef7b9
4 changed files with 51 additions and 30 deletions

View File

@@ -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<Boolean> waterlogged = (Property<Boolean>) 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;

View File

@@ -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<CustomItem<ItemStack>> 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;

View File

@@ -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<Class<?>> classToLastIdCache = new Object2IntOpenHashMap<>();

View File

@@ -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