9
0
mirror of https://github.com/LeavesMC/Leaves.git synced 2025-12-20 15:29:35 +00:00
Files
LeavesMC/patches/server/0050-Carpet-alternative-block-placement-Protocol.patch
2023-04-04 23:27:25 +08:00

207 lines
11 KiB
Diff

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 aba3f4655bdb830ca3fb7e4009d3fc7bdb207f85..2d7a97b5e0c44d571c59fa8889992be71fb9efc2 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -1946,7 +1946,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;
+ }
+}