From c60260ea5ce7645d5f39a1aad669388149600721 Mon Sep 17 00:00:00 2001 From: Theta-Dev Date: Fri, 22 Oct 2021 13:35:05 +0200 Subject: [PATCH 1/2] Fix #40 wand replacing half slabs Fix destruction wand removing blocks not facing the player --- gradle.properties | 2 +- .../thetadev/constructionwand/basics/WandUtil.java | 13 +++++++++++-- .../wand/action/ActionDestruction.java | 10 +++++++--- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/gradle.properties b/gradle.properties index 137e9cf..a893bfc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,4 +8,4 @@ mcp_channel=official mcp_mappings=1.17.1 botania=1.16.2-405 version_major=2 -version_minor=3 \ No newline at end of file +version_minor=4 \ No newline at end of file diff --git a/src/main/java/thetadev/constructionwand/basics/WandUtil.java b/src/main/java/thetadev/constructionwand/basics/WandUtil.java index 6b4db45..0ce3056 100644 --- a/src/main/java/thetadev/constructionwand/basics/WandUtil.java +++ b/src/main/java/thetadev/constructionwand/basics/WandUtil.java @@ -11,9 +11,11 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraftforge.common.MinecraftForge; @@ -22,6 +24,7 @@ import net.minecraftforge.event.world.BlockEvent; import thetadev.constructionwand.ConstructionWand; import thetadev.constructionwand.containers.ContainerManager; import thetadev.constructionwand.items.wand.ItemWand; +import thetadev.constructionwand.wand.WandItemUseContext; import javax.annotation.Nullable; import java.util.ArrayList; @@ -187,13 +190,19 @@ public class WandUtil /** * Tests if a wand can place a block at a certain position. - * This check is independent from the used block. + * This check is independent of the used block. */ public static boolean isPositionPlaceable(Level world, Player player, BlockPos pos, boolean replace) { if(!isPositionModifiable(world, player, pos)) return false; // If replace mode is off, target has to be air - return replace || world.isEmptyBlock(pos); + if(world.isEmptyBlock(pos)) return true; + + // Otherwise, check if the block can be replaced by a generic block + return replace && world.getBlockState(pos).canBeReplaced( + new WandItemUseContext(world, player, + new BlockHitResult(new Vec3(0, 0, 0), Direction.DOWN, pos, false), + pos, (BlockItem) Items.STONE)); } public static boolean isBlockRemovable(Level world, Player player, BlockPos pos) { diff --git a/src/main/java/thetadev/constructionwand/wand/action/ActionDestruction.java b/src/main/java/thetadev/constructionwand/wand/action/ActionDestruction.java index 335d908..182d632 100644 --- a/src/main/java/thetadev/constructionwand/wand/action/ActionDestruction.java +++ b/src/main/java/thetadev/constructionwand/wand/action/ActionDestruction.java @@ -38,14 +38,14 @@ public class ActionDestruction implements IWandAction HashSet allCandidates = new HashSet<>(); // Block face the wand was pointed at - Direction breakDirection = rayTraceResult.getDirection(); + Direction breakFace = rayTraceResult.getDirection(); // Block the wand was pointed at BlockPos startingPoint = rayTraceResult.getBlockPos(); BlockState targetBlock = world.getBlockState(rayTraceResult.getBlockPos()); // Is break direction allowed by lock? // Tried to break blocks from top/bottom face, so the wand should allow breaking in NS/EW direction - if(breakDirection == Direction.UP || breakDirection == Direction.DOWN) { + if(breakFace == Direction.UP || breakFace == Direction.DOWN) { if(options.testLock(WandOptions.LOCK.NORTHSOUTH) || options.testLock(WandOptions.LOCK.EASTWEST)) candidates.add(startingPoint); } @@ -56,6 +56,10 @@ public class ActionDestruction implements IWandAction // Process current candidates, stop when none are avaiable or block limit is reached while(!candidates.isEmpty() && destroySnapshots.size() < limit) { BlockPos currentCandidate = candidates.removeFirst(); + + // Only break blocks facing the player, with no blocks in between + if(!world.isEmptyBlock(currentCandidate.offset(breakFace.getNormal()))) continue; + try { BlockState candidateBlock = world.getBlockState(currentCandidate); @@ -66,7 +70,7 @@ public class ActionDestruction implements IWandAction if(snapshot == null) continue; destroySnapshots.add(snapshot); - switch(breakDirection) { + switch(breakFace) { case DOWN: case UP: if(options.testLock(WandOptions.LOCK.NORTHSOUTH)) { From bb48292c6f31854c2fa337fb9ae6a7b939b8abe5 Mon Sep 17 00:00:00 2001 From: Theta-Dev Date: Fri, 22 Oct 2021 17:36:35 +0200 Subject: [PATCH 2/2] Fix destruction behind permeable blocks --- src/main/java/thetadev/constructionwand/basics/WandUtil.java | 4 ++++ .../constructionwand/wand/action/ActionDestruction.java | 5 +++-- .../constructionwand/wand/supplier/SupplierInventory.java | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/thetadev/constructionwand/basics/WandUtil.java b/src/main/java/thetadev/constructionwand/basics/WandUtil.java index 0ce3056..418ec5c 100644 --- a/src/main/java/thetadev/constructionwand/basics/WandUtil.java +++ b/src/main/java/thetadev/constructionwand/basics/WandUtil.java @@ -214,6 +214,10 @@ public class WandUtil return true; } + public static boolean isBlockPermeable(Level world, BlockPos pos) { + return world.isEmptyBlock(pos) || world.getBlockState(pos).getCollisionShape(world, pos).isEmpty(); + } + public static boolean entitiesCollidingWithBlock(Level world, BlockState blockState, BlockPos pos) { VoxelShape shape = blockState.getCollisionShape(world, pos); if(!shape.isEmpty()) { diff --git a/src/main/java/thetadev/constructionwand/wand/action/ActionDestruction.java b/src/main/java/thetadev/constructionwand/wand/action/ActionDestruction.java index 182d632..9904c6d 100644 --- a/src/main/java/thetadev/constructionwand/wand/action/ActionDestruction.java +++ b/src/main/java/thetadev/constructionwand/wand/action/ActionDestruction.java @@ -10,6 +10,7 @@ import net.minecraft.world.phys.BlockHitResult; import thetadev.constructionwand.api.IWandAction; import thetadev.constructionwand.api.IWandSupplier; import thetadev.constructionwand.basics.ConfigServer; +import thetadev.constructionwand.basics.WandUtil; import thetadev.constructionwand.basics.option.WandOptions; import thetadev.constructionwand.wand.undo.DestroySnapshot; import thetadev.constructionwand.wand.undo.ISnapshot; @@ -57,8 +58,8 @@ public class ActionDestruction implements IWandAction while(!candidates.isEmpty() && destroySnapshots.size() < limit) { BlockPos currentCandidate = candidates.removeFirst(); - // Only break blocks facing the player, with no blocks in between - if(!world.isEmptyBlock(currentCandidate.offset(breakFace.getNormal()))) continue; + // Only break blocks facing the player, with no collidable blocks in between + if(!WandUtil.isBlockPermeable(world, currentCandidate.offset(breakFace.getNormal()))) continue; try { BlockState candidateBlock = world.getBlockState(currentCandidate); diff --git a/src/main/java/thetadev/constructionwand/wand/supplier/SupplierInventory.java b/src/main/java/thetadev/constructionwand/wand/supplier/SupplierInventory.java index 4e158ef..8a74155 100644 --- a/src/main/java/thetadev/constructionwand/wand/supplier/SupplierInventory.java +++ b/src/main/java/thetadev/constructionwand/wand/supplier/SupplierInventory.java @@ -6,6 +6,7 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; @@ -51,7 +52,7 @@ public class SupplierInventory implements IWandSupplier addBlockItem((BlockItem) offhandStack.getItem()); } // Otherwise use target block - else { + else if(target != null && target != Items.AIR) { addBlockItem(target); // Add replacement items