From 45cbc401777d8bd1d777581750b2efe239875edd Mon Sep 17 00:00:00 2001 From: Sebastian Hartte Date: Thu, 20 Aug 2020 22:58:49 +0200 Subject: [PATCH] Fix wrench interaction with part hosts. --- .../appeng/items/tools/NetworkToolItem.java | 17 +++--- .../items/tools/quartz/QuartzWrenchItem.java | 44 +++++++++++--- src/main/java/appeng/parts/PartPlacement.java | 59 +------------------ .../java/appeng/util/PartHostWrenching.java | 46 +++++++++++++++ 4 files changed, 92 insertions(+), 74 deletions(-) create mode 100644 src/main/java/appeng/util/PartHostWrenching.java diff --git a/src/main/java/appeng/items/tools/NetworkToolItem.java b/src/main/java/appeng/items/tools/NetworkToolItem.java index 5bfa2dae8..0840e7b16 100644 --- a/src/main/java/appeng/items/tools/NetworkToolItem.java +++ b/src/main/java/appeng/items/tools/NetworkToolItem.java @@ -32,6 +32,7 @@ import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.HitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import appeng.api.implementations.guiobjects.IGuiItem; @@ -53,6 +54,7 @@ import appeng.core.sync.packets.ClickPacket; import appeng.hooks.AEToolItem; import appeng.items.AEBaseItem; import appeng.items.contents.NetworkToolViewer; +import appeng.util.PartHostWrenching; import appeng.util.Platform; public class NetworkToolItem extends AEBaseItem implements IGuiItem, IAEWrench, AEToolItem { @@ -91,13 +93,17 @@ public class NetworkToolItem extends AEBaseItem implements IGuiItem, IAEWrench, final BlockEntity te = context.getWorld().getBlockEntity(context.getBlockPos()); if (te instanceof IPartHost) { - final SelectedPart part = ((IPartHost) te).selectPart(mop.getPos()); + Vec3d relativePosition = mop.getPos().subtract(mop.getBlockPos().getX(), mop.getBlockPos().getY(), + mop.getBlockPos().getZ()); + IPartHost host = (IPartHost) te; + final SelectedPart part = host.selectPart(relativePosition); if (part.part != null || part.facade != null) { if (part.part instanceof INetworkToolAgent && !((INetworkToolAgent) part.part).showNetworkInfo(mop)) { return ActionResult.FAIL; } else if (context.getPlayer().isInSneakingPose()) { - return ActionResult.PASS; + PartHostWrenching.wrenchPart(context.getWorld(), context.getBlockPos(), host, part); + return ActionResult.SUCCESS; } } } else if (te instanceof INetworkToolAgent && !((INetworkToolAgent) te).showNetworkInfo(mop)) { @@ -111,13 +117,6 @@ public class NetworkToolItem extends AEBaseItem implements IGuiItem, IAEWrench, return ActionResult.SUCCESS; } -// FIXME FABRIC: No direct equivalent -// FIXME FABRIC: Might already be handled by onItemUseFirst though -// FIXME FABRIC @Override -// FIXME FABRIC public boolean doesSneakBypassUse(ItemStack stack, WorldView world, BlockPos pos, PlayerEntity player) { -// FIXME FABRIC return true; -// FIXME FABRIC } - public boolean serverSideToolLogic(ItemUsageContext useContext) { BlockPos pos = useContext.getBlockPos(); PlayerEntity p = useContext.getPlayer(); diff --git a/src/main/java/appeng/items/tools/quartz/QuartzWrenchItem.java b/src/main/java/appeng/items/tools/quartz/QuartzWrenchItem.java index 943c046e6..504b0dae9 100644 --- a/src/main/java/appeng/items/tools/quartz/QuartzWrenchItem.java +++ b/src/main/java/appeng/items/tools/quartz/QuartzWrenchItem.java @@ -20,6 +20,7 @@ package appeng.items.tools.quartz; import net.minecraft.block.Block; import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -27,12 +28,18 @@ import net.minecraft.item.ItemUsageContext; import net.minecraft.util.ActionResult; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; import appeng.api.implementations.items.IAEWrench; +import appeng.api.parts.IPartHost; +import appeng.api.parts.SelectedPart; import appeng.api.util.DimensionalCoord; import appeng.block.AEBaseBlock; import appeng.hooks.AEToolItem; import appeng.items.AEBaseItem; +import appeng.parts.PartPlacement; +import appeng.util.PartHostWrenching; import appeng.util.Platform; public class QuartzWrenchItem extends AEBaseItem implements IAEWrench, AEToolItem { @@ -49,31 +56,52 @@ public class QuartzWrenchItem extends AEBaseItem implements IAEWrench, AEToolIte } boolean isHoldingShift = player.isInSneakingPose(); - if (!Platform.hasPermissions(new DimensionalCoord(context.getWorld(), context.getBlockPos()), player)) { + World world = context.getWorld(); + BlockPos pos = context.getBlockPos(); + if (!Platform.hasPermissions(new DimensionalCoord(world, pos), player)) { return ActionResult.FAIL; } - BlockState blockState = context.getWorld().getBlockState(context.getBlockPos()); + BlockState blockState = world.getBlockState(pos); Block block = blockState.getBlock(); if (isHoldingShift) { + + // Wrenching parts of cable buses or other part hosts + BlockEntity tile = world.getBlockEntity(pos); + IPartHost host = null; + if (tile instanceof IPartHost) { + host = (IPartHost) tile; + } + + if (host != null) { + if (!world.isClient) { + // Build the relative position within the part + Vec3d relPos = context.getHitPos().subtract(pos.getX(), pos.getY(), pos.getZ()); + + final SelectedPart sp = PartPlacement.selectPart(player, host, relPos); + + PartHostWrenching.wrenchPart(world, pos, host, sp); + } + return ActionResult.SUCCESS; + } + // Pass the use onto the block... - return block.onUse(blockState, context.getWorld(), context.getBlockPos(), player, context.getHand(), - new BlockHitResult(context.getHitPos(), context.getSide(), context.getBlockPos(), - context.hitsInsideBlock())); + return block.onUse(blockState, world, pos, player, context.getHand(), + new BlockHitResult(context.getHitPos(), context.getSide(), pos, context.hitsInsideBlock())); } if (block instanceof AEBaseBlock) { if (Platform.isClient()) { // TODO 1.10-R - if we return FAIL on client, action will not be sent to server. // Fix that in all Block#onItemUseFirst overrides. - return !context.getWorld().isClient ? ActionResult.SUCCESS : ActionResult.PASS; + return !world.isClient ? ActionResult.SUCCESS : ActionResult.PASS; } AEBaseBlock aeBlock = (AEBaseBlock) block; - if (aeBlock.rotateAroundFaceAxis(context.getWorld(), context.getBlockPos(), context.getSide())) { + if (aeBlock.rotateAroundFaceAxis(world, pos, context.getSide())) { player.swingHand(context.getHand()); - return !context.getWorld().isClient ? ActionResult.SUCCESS : ActionResult.FAIL; + return !world.isClient ? ActionResult.SUCCESS : ActionResult.FAIL; } } return ActionResult.PASS; diff --git a/src/main/java/appeng/parts/PartPlacement.java b/src/main/java/appeng/parts/PartPlacement.java index 9941362fb..e18ca9e32 100644 --- a/src/main/java/appeng/parts/PartPlacement.java +++ b/src/main/java/appeng/parts/PartPlacement.java @@ -18,9 +18,6 @@ package appeng.parts; -import java.util.ArrayList; -import java.util.List; - import net.fabricmc.fabric.api.event.player.UseBlockCallback; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -48,7 +45,6 @@ import appeng.api.definitions.IBlockDefinition; import appeng.api.parts.IFacadePart; import appeng.api.parts.IPartHost; import appeng.api.parts.IPartItem; -import appeng.api.parts.PartItemStack; import appeng.api.parts.SelectedPart; import appeng.api.util.AEPartLocation; import appeng.api.util.DimensionalCoord; @@ -85,56 +81,6 @@ public class PartPlacement { final BlockHitResult mop = world.rayTrace(rtc); ItemPlacementContext useContext = new ItemPlacementContext(new ItemUsageContext(player, hand, mop)); - if (!held.isEmpty() && Platform.isWrench(player, held, pos) && player.isInSneakingPose()) { - if (!Platform.hasPermissions(new DimensionalCoord(world, pos), player)) { - return ActionResult.FAIL; - } - - final BlockEntity tile = world.getBlockEntity(pos); - IPartHost host = null; - - if (tile instanceof IPartHost) { - host = (IPartHost) tile; - } - - if (host != null) { - if (!world.isClient) { - if (mop.getType() == HitResult.Type.BLOCK) { - final List is = new ArrayList<>(); - final SelectedPart sp = selectPart(player, host, - mop.getPos().add(-mop.getPos().getX(), -mop.getPos().getY(), -mop.getPos().getZ())); - - if (sp.part != null) { - is.add(sp.part.getItemStack(PartItemStack.WRENCH)); - sp.part.getDrops(is, true); - host.removePart(sp.side, false); - } - - if (sp.facade != null) { - is.add(sp.facade.getItemStack()); - host.getFacadeContainer().removeFacade(host, sp.side); - Platform.notifyBlocksOfNeighbors(world, pos); - } - - if (host.isEmpty()) { - host.cleanup(); - } - - if (!is.isEmpty()) { - Platform.spawnDrops(world, pos, is); - } - } - } else { - player.swingHand(hand); - NetworkHandler.instance() - .sendToServer(new PartPlacementPacket(pos, side, getEyeOffset(player), hand)); - } - return ActionResult.SUCCESS; - } - - return ActionResult.FAIL; - } - BlockEntity tile = world.getBlockEntity(pos); IPartHost host = null; @@ -178,6 +124,7 @@ public class PartPlacement { if (held.isEmpty()) { if (host != null && player.isInSneakingPose() && world.isAir(pos)) { if (mop.getType() == HitResult.Type.BLOCK) { + // FIXME FABRIC: This looks wrong Vec3d hitVec = mop.getPos().add(-mop.getPos().getX(), -mop.getPos().getY(), -mop.getPos().getZ()); final SelectedPart sPart = selectPart(player, host, hitVec); if (sPart != null && sPart.part != null) { @@ -323,7 +270,7 @@ public class PartPlacement { return getEyeHeight(); } - private static SelectedPart selectPart(final PlayerEntity player, final IPartHost host, final Vec3d pos) { + public static SelectedPart selectPart(final PlayerEntity player, final IPartHost host, final Vec3d pos) { AppEng.instance().setPartInteractionPlayer(player); try { return host.selectPart(pos); @@ -401,8 +348,6 @@ public class PartPlacement { // FIXME FABRIC NetworkHandler.instance().sendToServer(new ClickPacket(event.getHand())); // FIXME FABRIC } // FIXME FABRIC } -// FIXME FABRIC } else if (event instanceof PlayerInteractEvent.RightClickBlock && !event.getPlayer().world.isClient) { -// FIXME FABRIC // FIXME FABRIC } // FIXME FABRIC } diff --git a/src/main/java/appeng/util/PartHostWrenching.java b/src/main/java/appeng/util/PartHostWrenching.java new file mode 100644 index 000000000..d0347142d --- /dev/null +++ b/src/main/java/appeng/util/PartHostWrenching.java @@ -0,0 +1,46 @@ +package appeng.util; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import appeng.api.parts.IPartHost; +import appeng.api.parts.PartItemStack; +import appeng.api.parts.SelectedPart; + +/** + * Support functionality for using a wrench on parts attached to a part host. + */ +public final class PartHostWrenching { + + private PartHostWrenching() { + } + + public static void wrenchPart(World world, BlockPos pos, IPartHost host, SelectedPart sp) { + final List is = new ArrayList<>(); + + if (sp.part != null) { + is.add(sp.part.getItemStack(PartItemStack.WRENCH)); + sp.part.getDrops(is, true); + host.removePart(sp.side, false); + } + + if (sp.facade != null) { + is.add(sp.facade.getItemStack()); + host.getFacadeContainer().removeFacade(host, sp.side); + Platform.notifyBlocksOfNeighbors(world, pos); + } + + if (host.isEmpty()) { + host.cleanup(); + } + + if (!is.isEmpty()) { + Platform.spawnDrops(world, pos, is); + } + } + +}