Fix wrench interaction with part hosts.

This commit is contained in:
Sebastian Hartte
2020-08-20 22:58:49 +02:00
parent 0e7e9313ee
commit 45cbc40177
4 changed files with 92 additions and 74 deletions
@@ -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();
@@ -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;
+2 -57
View File
@@ -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<ItemStack> 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 }
@@ -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<ItemStack> 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);
}
}
}