Implements opening containers from items with and without a block context.
This commit is contained in:
@@ -23,16 +23,16 @@ import appeng.api.parts.IPartHost;
|
||||
import appeng.api.util.AEPartLocation;
|
||||
import appeng.api.util.DimensionalCoord;
|
||||
import appeng.parts.AEBasePart;
|
||||
import appeng.parts.misc.PartInterface;
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.netty.handler.codec.DecoderException;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import org.apache.commons.lang3.NotImplementedException;
|
||||
|
||||
/**
|
||||
* Describes how a container the player has opened was originally
|
||||
@@ -47,7 +47,16 @@ import org.apache.commons.lang3.NotImplementedException;
|
||||
public final class ContainerLocator {
|
||||
|
||||
private enum Type {
|
||||
ITEM,
|
||||
/**
|
||||
* An item used from the player's inventory.
|
||||
*/
|
||||
PLAYER_INVENTORY,
|
||||
/**
|
||||
* An item used from the player's inventory, but right-clicked
|
||||
* on a block face, has block position and side in addition to the
|
||||
* above.
|
||||
*/
|
||||
PLAYER_INVENTORY_WITH_BLOCK_CONTEXT,
|
||||
BLOCK,
|
||||
PART
|
||||
}
|
||||
@@ -82,9 +91,38 @@ public final class ContainerLocator {
|
||||
return new ContainerLocator(Type.PART, -1, dimensionId, te.getPos(), AEPartLocation.fromFacing(side));
|
||||
}
|
||||
|
||||
public static ContainerLocator forHand(Hand hand) {
|
||||
// FIXME can we get an inventory location for the hand?
|
||||
throw new IllegalStateException();
|
||||
/**
|
||||
* Construct a container locator for an item being used on a block. The item could still open a container
|
||||
* for itself, but it might also open a special container for the block being right-clicked.
|
||||
*/
|
||||
public static ContainerLocator forItemUseContext(ItemUseContext context) {
|
||||
PlayerEntity player = context.getPlayer();
|
||||
if (player == null) {
|
||||
throw new IllegalArgumentException("Cannot open a container without a player");
|
||||
}
|
||||
int dimensionId = player.world.getDimension().getType().getId();
|
||||
int slot = getPlayerInventorySlotFromHand(player, context.getHand());
|
||||
AEPartLocation side = AEPartLocation.fromFacing(context.getFace());
|
||||
return new ContainerLocator(Type.PLAYER_INVENTORY_WITH_BLOCK_CONTEXT, slot, dimensionId, context.getPos(), side);
|
||||
}
|
||||
|
||||
public static ContainerLocator forHand(PlayerEntity player, Hand hand) {
|
||||
int slot = getPlayerInventorySlotFromHand(player, hand);
|
||||
return new ContainerLocator(Type.PLAYER_INVENTORY, slot, -1, null, null);
|
||||
}
|
||||
|
||||
private static int getPlayerInventorySlotFromHand(PlayerEntity player, Hand hand) {
|
||||
ItemStack is = player.getHeldItem(hand);
|
||||
if (is.isEmpty()) {
|
||||
throw new IllegalArgumentException("Cannot open an item-inventory with empty hands");
|
||||
}
|
||||
int invSize = player.inventory.getSizeInventory();
|
||||
for (int i = 0; i < invSize; i++) {
|
||||
if (player.inventory.getStackInSlot(i) == is) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Could not find item held in hand " + hand + " in player inventory");
|
||||
}
|
||||
|
||||
public static ContainerLocator forPart(AEBasePart part) {
|
||||
@@ -100,11 +138,11 @@ public final class ContainerLocator {
|
||||
}
|
||||
|
||||
public boolean hasItemIndex() {
|
||||
return type == Type.ITEM;
|
||||
return type == Type.PLAYER_INVENTORY || type == Type.PLAYER_INVENTORY_WITH_BLOCK_CONTEXT;
|
||||
}
|
||||
|
||||
public int getItemIndex() {
|
||||
Preconditions.checkState(type == Type.ITEM);
|
||||
Preconditions.checkState(hasItemIndex());
|
||||
return itemIndex;
|
||||
}
|
||||
|
||||
@@ -113,36 +151,43 @@ public final class ContainerLocator {
|
||||
}
|
||||
|
||||
public boolean hasBlockPos() {
|
||||
return type == Type.BLOCK || type == Type.PART;
|
||||
return type == Type.BLOCK || type == Type.PART || type == Type.PLAYER_INVENTORY_WITH_BLOCK_CONTEXT;
|
||||
}
|
||||
|
||||
public BlockPos getBlockPos() {
|
||||
Preconditions.checkState(type == Type.BLOCK || type == Type.PART);
|
||||
Preconditions.checkState(hasBlockPos());
|
||||
return blockPos;
|
||||
}
|
||||
|
||||
public boolean hasSide() {
|
||||
return type == Type.PART;
|
||||
return type == Type.PART || type == Type.PLAYER_INVENTORY_WITH_BLOCK_CONTEXT;
|
||||
}
|
||||
|
||||
public AEPartLocation getSide() {
|
||||
Preconditions.checkState(type == Type.PART);
|
||||
Preconditions.checkState(hasSide());
|
||||
return side;
|
||||
}
|
||||
|
||||
public void write(PacketBuffer buf) {
|
||||
switch (type) {
|
||||
case ITEM:
|
||||
case PLAYER_INVENTORY:
|
||||
buf.writeByte(0);
|
||||
buf.writeInt(itemIndex);
|
||||
break;
|
||||
case BLOCK:
|
||||
case PLAYER_INVENTORY_WITH_BLOCK_CONTEXT:
|
||||
buf.writeByte(1);
|
||||
buf.writeInt(itemIndex);
|
||||
buf.writeInt(dimensionId);
|
||||
buf.writeBlockPos(blockPos);
|
||||
buf.writeByte(side.ordinal());
|
||||
break;
|
||||
case BLOCK:
|
||||
buf.writeByte(22);
|
||||
buf.writeInt(dimensionId);
|
||||
buf.writeBlockPos(blockPos);
|
||||
break;
|
||||
case PART:
|
||||
buf.writeByte(2);
|
||||
buf.writeByte(3);
|
||||
buf.writeInt(dimensionId);
|
||||
buf.writeBlockPos(blockPos);
|
||||
buf.writeByte(side.ordinal());
|
||||
@@ -157,13 +202,21 @@ public final class ContainerLocator {
|
||||
switch (type) {
|
||||
case 0:
|
||||
return new ContainerLocator(
|
||||
Type.ITEM,
|
||||
Type.PLAYER_INVENTORY,
|
||||
buf.readInt(),
|
||||
-1,
|
||||
null,
|
||||
null
|
||||
);
|
||||
case 1:
|
||||
return new ContainerLocator(
|
||||
Type.PLAYER_INVENTORY_WITH_BLOCK_CONTEXT,
|
||||
buf.readInt(),
|
||||
buf.readInt(),
|
||||
buf.readBlockPos(),
|
||||
AEPartLocation.values()[buf.readByte()]
|
||||
);
|
||||
case 2:
|
||||
return new ContainerLocator(
|
||||
Type.BLOCK,
|
||||
-1,
|
||||
@@ -171,7 +224,7 @@ public final class ContainerLocator {
|
||||
buf.readBlockPos(),
|
||||
null
|
||||
);
|
||||
case 2:
|
||||
case 3:
|
||||
return new ContainerLocator(
|
||||
Type.PART,
|
||||
-1,
|
||||
@@ -184,4 +237,25 @@ public final class ContainerLocator {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder result = new StringBuilder(type.name());
|
||||
result.append('{');
|
||||
if (hasItemIndex()) {
|
||||
result.append("slot=").append(itemIndex).append(',');
|
||||
}
|
||||
if (hasBlockPos()) {
|
||||
result.append("dim=").append(dimensionId).append(',');
|
||||
result.append("pos=").append(blockPos).append(',');
|
||||
}
|
||||
if (hasSide()) {
|
||||
result.append("side=").append(side).append(',');
|
||||
}
|
||||
if (result.charAt(result.length() - 1) == ',') {
|
||||
result.setLength(result.length() - 1);
|
||||
}
|
||||
result.append('}');
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user