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/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java index ebee8de2ed831755b6fd154f6cc77ac993839bb9..1015b3c5f6969709bb8ebfbd66eb9cede444385c 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 9522e646529f3d849471931b4b3c0d133e7fcfc5..5cf87860455ca05363685c192dc34a273edc2469 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java @@ -411,6 +411,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/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; + } +}