From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: violetc <58360096+s-yh-china@users.noreply.github.com> Date: Thu, 8 Dec 2022 19:40:00 +0800 Subject: [PATCH] Carpet alternative block placement Protocol This patch is Powered by carpet-extra(https://github.com/gnembon/carpet-extra) diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java index eb2ff842a1b8534d4d23e1303010c51af2ecaafc..ef46f5e8d425703a71064a8afe2115a5e98c29fa 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1938,7 +1938,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic Vec3 vec3d2 = vec3d.subtract(vec3d1); double d0 = 1.0000001D; - if (Math.abs(vec3d2.x()) < 1.0000001D && Math.abs(vec3d2.y()) < 1.0000001D && Math.abs(vec3d2.z()) < 1.0000001D) { + if (top.leavesmc.leaves.LeavesConfig.carpetAlternativeBlockPlacement || (Math.abs(vec3d2.x()) < 1.0000001D && Math.abs(vec3d2.y()) < 1.0000001D && Math.abs(vec3d2.z()) < 1.0000001D)) { // Leaves - carpetAlternativeBlockPlacement Direction enumdirection = movingobjectpositionblock.getDirection(); this.player.resetLastActionTime(); diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java index b0204af850ee182773ad458208cccd946ad148d5..3ab714721b51b039291b8e8a4b4da5118e18f5b7 100644 --- a/src/main/java/net/minecraft/world/item/BlockItem.java +++ b/src/main/java/net/minecraft/world/item/BlockItem.java @@ -158,7 +158,7 @@ public class BlockItem extends Item { @Nullable protected BlockState getPlacementState(BlockPlaceContext context) { - BlockState iblockdata = this.getBlock().getStateForPlacement(context); + BlockState iblockdata = this.getBlock().getRealStateForPlacement(context); // Leaves - carpetAlternativeBlockPlacement return iblockdata != null && this.canPlace(context, iblockdata) ? iblockdata : null; } diff --git a/src/main/java/net/minecraft/world/item/StandingAndWallBlockItem.java b/src/main/java/net/minecraft/world/item/StandingAndWallBlockItem.java index 39b8b3675ac58409e05fac07e07c8016c5280d81..928b1ece5b094dee8a5e37bfd3afd626cb1bd03a 100644 --- a/src/main/java/net/minecraft/world/item/StandingAndWallBlockItem.java +++ b/src/main/java/net/minecraft/world/item/StandingAndWallBlockItem.java @@ -34,7 +34,7 @@ public class StandingAndWallBlockItem extends BlockItem { @Nullable @Override protected BlockState getPlacementState(BlockPlaceContext context) { - BlockState iblockdata = this.wallBlock.getStateForPlacement(context); + BlockState iblockdata = this.wallBlock.getRealStateForPlacement(context); // Leaves - carpetAlternativeBlockPlacement BlockState iblockdata1 = null; Level world = context.getLevel(); BlockPos blockposition = context.getClickedPos(); @@ -45,7 +45,7 @@ public class StandingAndWallBlockItem extends BlockItem { Direction enumdirection = aenumdirection[j]; if (enumdirection != this.attachmentDirection.getOpposite()) { - BlockState iblockdata2 = enumdirection == this.attachmentDirection ? this.getBlock().getStateForPlacement(context) : iblockdata; + BlockState iblockdata2 = enumdirection == this.attachmentDirection ? this.getBlock().getRealStateForPlacement(context) : iblockdata; // Leaves - carpetAlternativeBlockPlacement if (iblockdata2 != null && this.canPlace(world, iblockdata2, blockposition)) { iblockdata1 = iblockdata2; diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java index 4f91e4832a94c3facbc711fcae4cb5ad540a5ca0..08e456ee6a537c5cc8b6314f9f899b25a12f352d 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java @@ -423,6 +423,19 @@ public class Block extends BlockBehaviour implements ItemLike { public void stepOn(Level world, BlockPos pos, BlockState state, Entity entity) {} + // Leaves start - carpetAlternativeBlockPlacement + @Nullable + public BlockState getRealStateForPlacement(BlockPlaceContext ctx) { + if (top.leavesmc.leaves.LeavesConfig.carpetAlternativeBlockPlacement) { + BlockState tryState = top.leavesmc.leaves.protocol.CarpetAlternativeBlockPlacement.alternativeBlockPlacement(this, ctx); + if (tryState != null) { + return tryState; + } + } + return getStateForPlacement(ctx); + } + // Leaves end - carpetAlternativeBlockPlacement + @Nullable public BlockState getStateForPlacement(BlockPlaceContext ctx) { return this.defaultBlockState(); diff --git a/src/main/java/top/leavesmc/leaves/LeavesConfig.java b/src/main/java/top/leavesmc/leaves/LeavesConfig.java index 35aab7f3d0d67fdbee2f438070b2a88ecd269083..60f21d16cd1bdac17bd8f29398edab7024b369f2 100644 --- a/src/main/java/top/leavesmc/leaves/LeavesConfig.java +++ b/src/main/java/top/leavesmc/leaves/LeavesConfig.java @@ -427,6 +427,15 @@ public final class LeavesConfig { jadeProtocol = getBoolean("settings.protocol.jade-protocol", jadeProtocol); } + public static boolean carpetAlternativeBlockPlacement = false; + private static void carpetAlternativeBlockPlacement() { + carpetAlternativeBlockPlacement = getBoolean("settings.protocol.carpet-alternative-block-placement", carpetAlternativeBlockPlacement); + if (carpetAlternativeBlockPlacement) { + LeavesLogger.LOGGER.warning("If use carpet-alternative-block-placement, too far away form hit block check of UseItemOnPacket will be broken."); + LeavesLogger.LOGGER.warning("If you do not use it, you need to set it to false"); + } + } + public static final class WorldConfig { public final String worldName; diff --git a/src/main/java/top/leavesmc/leaves/protocol/CarpetAlternativeBlockPlacement.java b/src/main/java/top/leavesmc/leaves/protocol/CarpetAlternativeBlockPlacement.java new file mode 100644 index 0000000000000000000000000000000000000000..848c380ed3d9755bab680b1e244a6024110bc383 --- /dev/null +++ b/src/main/java/top/leavesmc/leaves/protocol/CarpetAlternativeBlockPlacement.java @@ -0,0 +1,101 @@ +package top.leavesmc.leaves.protocol; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.block.BedBlock; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.ComparatorBlock; +import net.minecraft.world.level.block.RepeaterBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.ComparatorMode; +import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.block.state.properties.Half; +import net.minecraft.world.level.block.state.properties.Property; +import net.minecraft.world.level.block.state.properties.SlabType; +import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.Nullable; + +public class CarpetAlternativeBlockPlacement { + + @Nullable + public static BlockState alternativeBlockPlacement(@NotNull Block block, @NotNull BlockPlaceContext context) { + Vec3 hitPos = context.getClickLocation(); + BlockPos blockPos = context.getClickedPos(); + double relativeHitX = hitPos.x - blockPos.getX(); + BlockState state = block.getStateForPlacement(context); + + if (relativeHitX < 2 || state == null) { + return null; + } + + DirectionProperty directionProp = getFirstDirectionProperty(state); + int protocolValue = ((int) relativeHitX - 2) / 2; + + if (directionProp != null) { + Direction origFacing = state.getValue(directionProp); + Direction facing = origFacing; + int facingIndex = protocolValue & 0xF; + + if (facingIndex == 6) { + facing = facing.getOpposite(); + } else if (facingIndex <= 5) { + facing = Direction.from3DDataValue(facingIndex); + } + + if (!directionProp.getPossibleValues().contains(facing)) { + facing = context.getPlayer().getDirection().getOpposite(); + } + + if (facing != origFacing && directionProp.getPossibleValues().contains(facing)) { + if (state.getBlock() instanceof BedBlock) { + BlockPos headPos = blockPos.relative(facing); + + if (!context.getLevel().getBlockState(headPos).canBeReplaced(context)) { + return null; + } + } + + state = state.setValue(directionProp, facing); + } + } else if (state.hasProperty(BlockStateProperties.AXIS)) { + Direction.Axis axis = Direction.Axis.VALUES[protocolValue % 3]; + state = state.setValue(BlockStateProperties.AXIS, axis); + } + + protocolValue &= 0xFFFFFFF0; + + if (protocolValue >= 16) { + if (block instanceof RepeaterBlock) { + Integer delay = (protocolValue / 16); + + if (RepeaterBlock.DELAY.getPossibleValues().contains(delay)) { + state = state.setValue(RepeaterBlock.DELAY, delay); + } + } else if (protocolValue == 16) { + if (block instanceof ComparatorBlock) { + state = state.setValue(ComparatorBlock.MODE, ComparatorMode.SUBTRACT); + } else if (state.hasProperty(BlockStateProperties.HALF) && state.getValue(BlockStateProperties.HALF) == Half.BOTTOM) { + state = state.setValue(BlockStateProperties.HALF, Half.TOP); + } else if (state.hasProperty(BlockStateProperties.SLAB_TYPE) && state.getValue(BlockStateProperties.SLAB_TYPE) == SlabType.BOTTOM) { + state = state.setValue(BlockStateProperties.SLAB_TYPE, SlabType.TOP); + } + } + } + + return state; + } + + @Nullable + public static DirectionProperty getFirstDirectionProperty(@NotNull BlockState state) { + for (Property prop : state.getProperties()) { + if (prop instanceof DirectionProperty) { + return (DirectionProperty) prop; + } + } + return null; + } +}