mirror of
https://github.com/Ellpeck/PrettyPipes.git
synced 2024-11-22 11:53:29 +01:00
more crafting terminal work + network locks
This commit is contained in:
parent
67e7da2b73
commit
ccc981fee3
17 changed files with 330 additions and 60 deletions
|
@ -76,7 +76,7 @@ public class ItemFilter extends ItemStackHandler {
|
|||
} else if (id == 1 && this.canPopulateFromInventories) {
|
||||
// populate filter from inventories
|
||||
for (Direction direction : Direction.values()) {
|
||||
IItemHandler handler = this.pipe.getItemHandler(direction, false);
|
||||
IItemHandler handler = this.pipe.getItemHandler(direction, null);
|
||||
if (handler == null)
|
||||
continue;
|
||||
for (int i = 0; i < handler.getSlots(); i++) {
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package de.ellpeck.prettypipes.network;
|
||||
|
||||
public class NetworkLock {
|
||||
|
||||
public final NetworkLocation location;
|
||||
public final int slot;
|
||||
public final int amount;
|
||||
|
||||
public NetworkLock(NetworkLocation location, int slot, int amount) {
|
||||
this.location = location;
|
||||
this.slot = slot;
|
||||
this.amount = amount;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package de.ellpeck.prettypipes.network;
|
||||
|
||||
import de.ellpeck.prettypipes.Utility;
|
||||
import de.ellpeck.prettypipes.pipe.IPipeConnectable;
|
||||
import de.ellpeck.prettypipes.pipe.PipeTileEntity;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.ILiquidContainer;
|
||||
|
@ -172,10 +173,13 @@ public class PipeItem implements INBTSerializable<CompoundNBT>, ILiquidContainer
|
|||
|
||||
private ItemStack store(PipeTileEntity currPipe) {
|
||||
Direction dir = Utility.getDirectionFromOffset(this.destInventory, this.getDestPipe());
|
||||
IItemHandler handler = currPipe.getItemHandler(dir, true);
|
||||
if (handler == null)
|
||||
return this.stack;
|
||||
return ItemHandlerHelper.insertItemStacked(handler, this.stack, false);
|
||||
IPipeConnectable connectable = currPipe.getPipeConnectable(dir);
|
||||
if (connectable != null)
|
||||
return connectable.insertItem(currPipe.getWorld(), currPipe.getPos(), dir, this);
|
||||
IItemHandler handler = currPipe.getItemHandler(dir, this);
|
||||
if (handler != null)
|
||||
return ItemHandlerHelper.insertItemStacked(handler, this.stack, false);
|
||||
return this.stack;
|
||||
}
|
||||
|
||||
private PipeTileEntity getNextTile(PipeTileEntity currPipe, boolean progress) {
|
||||
|
|
|
@ -50,6 +50,7 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
|
|||
private final Map<BlockPos, List<BlockPos>> nodeToConnectedNodes = new HashMap<>();
|
||||
private final Map<BlockPos, PipeTileEntity> tileCache = new HashMap<>();
|
||||
private final ListMultimap<BlockPos, PipeItem> pipeItems = ArrayListMultimap.create();
|
||||
private final ListMultimap<BlockPos, NetworkLock> networkLocks = ArrayListMultimap.create();
|
||||
private final World world;
|
||||
|
||||
public PipeNetwork(World world) {
|
||||
|
@ -189,7 +190,7 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
|
|||
if (!pipe.canNetworkSee())
|
||||
continue;
|
||||
for (Direction dir : Direction.values()) {
|
||||
IItemHandler handler = pipe.getItemHandler(dir, false);
|
||||
IItemHandler handler = pipe.getItemHandler(dir, null);
|
||||
if (handler == null)
|
||||
continue;
|
||||
// check if this handler already exists (double-connected pipes, double chests etc.)
|
||||
|
@ -210,6 +211,24 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
|
|||
return info;
|
||||
}
|
||||
|
||||
public void createNetworkLock(NetworkLock lock) {
|
||||
this.networkLocks.put(lock.location.pos, lock);
|
||||
}
|
||||
|
||||
public void resolveNetworkLock(NetworkLock lock) {
|
||||
this.networkLocks.remove(lock.location.pos, lock);
|
||||
}
|
||||
|
||||
public List<NetworkLock> getNetworkLocks(BlockPos pos) {
|
||||
return this.networkLocks.get(pos);
|
||||
}
|
||||
|
||||
public int getLockedAmount(BlockPos pos, int slot) {
|
||||
return this.getNetworkLocks(pos).stream()
|
||||
.filter(l -> l.slot == slot)
|
||||
.mapToInt(l -> l.amount).sum();
|
||||
}
|
||||
|
||||
private void refreshNode(BlockPos pos, BlockState state) {
|
||||
this.startProfile("refresh_node");
|
||||
this.graph.removeAllEdges(new ArrayList<>(this.graph.edgesOf(pos)));
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package de.ellpeck.prettypipes.pipe;
|
||||
|
||||
import de.ellpeck.prettypipes.network.PipeItem;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
@ -8,9 +10,13 @@ import net.minecraftforge.items.IItemHandler;
|
|||
|
||||
public interface IPipeConnectable {
|
||||
|
||||
ConnectionType getConnectionType(World world, BlockPos pos, BlockState state, BlockPos pipePos, Direction direction);
|
||||
ConnectionType getConnectionType(World world, BlockPos pipePos, Direction direction);
|
||||
|
||||
default IItemHandler getItemHandler(World world, BlockPos pos, BlockState state, BlockPos pipePos, Direction direction, boolean force) {
|
||||
default IItemHandler getItemHandler(World world, BlockPos pipePos, Direction direction, PipeItem item) {
|
||||
return null;
|
||||
}
|
||||
|
||||
default ItemStack insertItem(World world, BlockPos pipePos, Direction direction, PipeItem item) {
|
||||
return item.stack;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ public class PipeBlock extends ContainerBlock implements IPipeConnectable {
|
|||
PipeTileEntity tile = Utility.getTileEntity(PipeTileEntity.class, worldIn, pos);
|
||||
if (tile == null)
|
||||
return ActionResultType.PASS;
|
||||
if (!tile.isConnectedInventory(false))
|
||||
if (!tile.isConnectedInventory())
|
||||
return ActionResultType.PASS;
|
||||
if (!worldIn.isRemote)
|
||||
NetworkHooks.openGui((ServerPlayerEntity) player, tile, pos);
|
||||
|
@ -161,7 +161,7 @@ public class PipeBlock extends ContainerBlock implements IPipeConnectable {
|
|||
BlockState offState = world.getBlockState(offset);
|
||||
Block block = offState.getBlock();
|
||||
if (block instanceof IPipeConnectable)
|
||||
return ((IPipeConnectable) block).getConnectionType(world, offset, offState, pos, direction.getOpposite());
|
||||
return ((IPipeConnectable) block).getConnectionType(world, pos, direction);
|
||||
TileEntity tile = world.getTileEntity(offset);
|
||||
if (tile != null) {
|
||||
IItemHandler handler = tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, direction.getOpposite()).orElse(null);
|
||||
|
@ -185,7 +185,7 @@ public class PipeBlock extends ContainerBlock implements IPipeConnectable {
|
|||
|
||||
public static void onStateChanged(World world, BlockPos pos, BlockState newState) {
|
||||
PipeTileEntity tile = Utility.getTileEntity(PipeTileEntity.class, world, pos);
|
||||
if (tile != null && !tile.isConnectedInventory(false))
|
||||
if (tile != null && !tile.isConnectedInventory())
|
||||
Utility.dropInventory(tile, tile.modules);
|
||||
|
||||
PipeNetwork network = PipeNetwork.get(world);
|
||||
|
@ -252,8 +252,9 @@ public class PipeBlock extends ContainerBlock implements IPipeConnectable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ConnectionType getConnectionType(World world, BlockPos pos, BlockState state, BlockPos pipePos, Direction direction) {
|
||||
if (state.get(DIRECTIONS.get(direction)) == ConnectionType.BLOCKED)
|
||||
public ConnectionType getConnectionType(World world, BlockPos pipePos, Direction direction) {
|
||||
BlockState state = world.getBlockState(pipePos.offset(direction));
|
||||
if (state.get(DIRECTIONS.get(direction.getOpposite())) == ConnectionType.BLOCKED)
|
||||
return ConnectionType.BLOCKED;
|
||||
return ConnectionType.CONNECTED;
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
|||
if (!force && this.streamModules().anyMatch(m -> !m.getRight().canAcceptItem(m.getLeft(), this, stack)))
|
||||
return null;
|
||||
for (Direction dir : Direction.values()) {
|
||||
IItemHandler handler = this.getItemHandler(dir, force);
|
||||
IItemHandler handler = this.getItemHandler(dir, null);
|
||||
if (handler == null)
|
||||
continue;
|
||||
if (!ItemHandlerHelper.insertItem(handler, stack, true).isEmpty())
|
||||
|
@ -192,7 +192,7 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
|||
return this.streamModules().allMatch(m -> m.getRight().canPipeWork(m.getLeft(), this));
|
||||
}
|
||||
|
||||
public IItemHandler getItemHandler(Direction dir, boolean force) {
|
||||
public IItemHandler getItemHandler(Direction dir, PipeItem item) {
|
||||
if (!this.isConnected(dir))
|
||||
return null;
|
||||
BlockPos pos = this.pos.offset(dir);
|
||||
|
@ -208,21 +208,25 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
|||
if (handler != null)
|
||||
return handler;
|
||||
}
|
||||
BlockState state = this.world.getBlockState(pos);
|
||||
if (state.getBlock() instanceof IPipeConnectable) {
|
||||
IItemHandler handler = ((IPipeConnectable) state.getBlock()).getItemHandler(this.world, pos, state, this.pos, dir, force);
|
||||
if (handler != null)
|
||||
return handler;
|
||||
}
|
||||
IPipeConnectable connectable = this.getPipeConnectable(dir);
|
||||
if (connectable != null)
|
||||
return connectable.getItemHandler(this.world, this.pos, dir, item);
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isConnectedInventory(Direction dir, boolean force) {
|
||||
return this.getItemHandler(dir, force) != null;
|
||||
public IPipeConnectable getPipeConnectable(Direction dir) {
|
||||
BlockState state = this.world.getBlockState(this.pos.offset(dir));
|
||||
if (state.getBlock() instanceof IPipeConnectable)
|
||||
return (IPipeConnectable) state.getBlock();
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isConnectedInventory(boolean force) {
|
||||
return Arrays.stream(Direction.values()).anyMatch(dir -> this.isConnectedInventory(dir, force));
|
||||
public boolean isConnectedInventory(Direction dir) {
|
||||
return this.getItemHandler(dir, null) != null;
|
||||
}
|
||||
|
||||
public boolean isConnectedInventory() {
|
||||
return Arrays.stream(Direction.values()).anyMatch(this::isConnectedInventory);
|
||||
}
|
||||
|
||||
public boolean canNetworkSee() {
|
||||
|
|
|
@ -39,7 +39,7 @@ public class ExtractionModuleItem extends ModuleItem {
|
|||
|
||||
PipeNetwork network = PipeNetwork.get(tile.getWorld());
|
||||
for (Direction dir : Direction.values()) {
|
||||
IItemHandler handler = tile.getItemHandler(dir, false);
|
||||
IItemHandler handler = tile.getItemHandler(dir, null);
|
||||
if (handler == null)
|
||||
continue;
|
||||
for (int j = 0; j < handler.getSlots(); j++) {
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
package de.ellpeck.prettypipes.terminal;
|
||||
|
||||
import de.ellpeck.prettypipes.terminal.containers.ItemTerminalGui;
|
||||
import net.minecraft.block.ContainerBlock;
|
||||
import de.ellpeck.prettypipes.Utility;
|
||||
import de.ellpeck.prettypipes.misc.ItemEqualityType;
|
||||
import de.ellpeck.prettypipes.network.PipeItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
@ -14,4 +21,29 @@ public class CraftingTerminalBlock extends ItemTerminalBlock {
|
|||
public TileEntity createNewTileEntity(IBlockReader worldIn) {
|
||||
return new CraftingTerminalTileEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack insertItem(World world, BlockPos pipePos, Direction direction, PipeItem item) {
|
||||
BlockPos pos = pipePos.offset(direction);
|
||||
CraftingTerminalTileEntity tile = Utility.getTileEntity(CraftingTerminalTileEntity.class, world, pos);
|
||||
if (tile != null) {
|
||||
int lowestFitting = -1;
|
||||
for (int i = 0; i < tile.craftItems.getSlots(); i++) {
|
||||
ItemStack stack = tile.getRequestedCraftItem(i);
|
||||
if (!ItemHandlerHelper.canItemStacksStackRelaxed(stack, item.stack))
|
||||
continue;
|
||||
if (lowestFitting < 0 || stack.getCount() < tile.getRequestedCraftItem(lowestFitting).getCount())
|
||||
lowestFitting = i;
|
||||
}
|
||||
ItemStack remain = item.stack;
|
||||
if (lowestFitting >= 0) {
|
||||
remain = tile.craftItems.insertItem(lowestFitting, item.stack, false);
|
||||
if (remain.isEmpty())
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
return ItemHandlerHelper.insertItemStacked(tile.items, remain, false);
|
||||
}
|
||||
return item.stack;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,17 +7,39 @@ import de.ellpeck.prettypipes.terminal.containers.ItemTerminalContainer;
|
|||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.inventory.container.Container;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TranslationTextComponent;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class CraftingTerminalTileEntity extends ItemTerminalTileEntity {
|
||||
|
||||
public final ItemStackHandler craftItems = new ItemStackHandler(9);
|
||||
|
||||
public CraftingTerminalTileEntity() {
|
||||
super(Registry.craftingTerminalTileEntity);
|
||||
}
|
||||
|
||||
public ItemStack getRequestedCraftItem(int slot) {
|
||||
// TODO put ghost slot contents here
|
||||
return this.craftItems.getStackInSlot(slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT compound) {
|
||||
compound.put("craft_items", this.craftItems.serializeNBT());
|
||||
return super.write(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundNBT compound) {
|
||||
this.craftItems.deserializeNBT(compound.getCompound("craft_items"));
|
||||
super.read(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITextComponent getDisplayName() {
|
||||
return new TranslationTextComponent("container." + PrettyPipes.ID + ".crafting_terminal");
|
||||
|
|
|
@ -25,6 +25,7 @@ import net.minecraft.world.IBlockReader;
|
|||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.network.NetworkHooks;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
@ -63,18 +64,17 @@ public class ItemTerminalBlock extends ContainerBlock implements IPipeConnectabl
|
|||
}
|
||||
|
||||
@Override
|
||||
public ConnectionType getConnectionType(World world, BlockPos pos, BlockState state, BlockPos pipePos, Direction direction) {
|
||||
public ConnectionType getConnectionType(World world, BlockPos pipePos, Direction direction) {
|
||||
return ConnectionType.CONNECTED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemHandler getItemHandler(World world, BlockPos pos, BlockState state, BlockPos pipePos, Direction direction, boolean force) {
|
||||
if (force) {
|
||||
ItemTerminalTileEntity tile = Utility.getTileEntity(ItemTerminalTileEntity.class, world, pos);
|
||||
if (tile != null)
|
||||
return tile.items;
|
||||
}
|
||||
return null;
|
||||
public ItemStack insertItem(World world, BlockPos pipePos, Direction direction, PipeItem item) {
|
||||
BlockPos pos = pipePos.offset(direction);
|
||||
ItemTerminalTileEntity tile = Utility.getTileEntity(ItemTerminalTileEntity.class, world, pos);
|
||||
if (tile != null)
|
||||
return ItemHandlerHelper.insertItemStacked(tile.items, item.stack, false);
|
||||
return item.stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -6,10 +6,7 @@ import de.ellpeck.prettypipes.Utility;
|
|||
import de.ellpeck.prettypipes.misc.EquatableItemStack;
|
||||
import de.ellpeck.prettypipes.misc.ItemEqualityType;
|
||||
import de.ellpeck.prettypipes.misc.ItemOrder;
|
||||
import de.ellpeck.prettypipes.network.NetworkItem;
|
||||
import de.ellpeck.prettypipes.network.NetworkLocation;
|
||||
import de.ellpeck.prettypipes.network.PipeItem;
|
||||
import de.ellpeck.prettypipes.network.PipeNetwork;
|
||||
import de.ellpeck.prettypipes.network.*;
|
||||
import de.ellpeck.prettypipes.packets.PacketHandler;
|
||||
import de.ellpeck.prettypipes.packets.PacketNetworkItems;
|
||||
import de.ellpeck.prettypipes.pipe.PipeTileEntity;
|
||||
|
@ -50,7 +47,7 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
|
|||
}
|
||||
};
|
||||
public Map<EquatableItemStack, NetworkItem> networkItems;
|
||||
private final Queue<Triple<NetworkLocation, Integer, Integer>> pendingRequests = new ArrayDeque<>();
|
||||
private final Queue<NetworkLock> pendingRequests = new ArrayDeque<>();
|
||||
|
||||
protected ItemTerminalTileEntity(TileEntityType<?> tileEntityTypeIn) {
|
||||
super(tileEntityTypeIn);
|
||||
|
@ -82,13 +79,11 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
|
|||
}
|
||||
|
||||
if (!this.pendingRequests.isEmpty()) {
|
||||
Triple<NetworkLocation, Integer, Integer> request = this.pendingRequests.remove();
|
||||
NetworkLocation location = request.getLeft();
|
||||
int slot = request.getMiddle();
|
||||
int amount = request.getRight();
|
||||
ItemStack extracted = location.handler.extractItem(slot, amount, true);
|
||||
if (network.routeItemToLocation(location.pipePos, location.pos, pipe.getPos(), this.pos, speed -> new PipeItem(extracted, speed))) {
|
||||
location.handler.extractItem(slot, extracted.getCount(), false);
|
||||
NetworkLock request = this.pendingRequests.remove();
|
||||
network.resolveNetworkLock(request);
|
||||
ItemStack extracted = request.location.handler.extractItem(request.slot, request.amount, true);
|
||||
if (network.routeItemToLocation(request.location.pipePos, request.location.pos, pipe.getPos(), this.pos, speed -> new PipeItem(extracted, speed))) {
|
||||
request.location.handler.extractItem(request.slot, extracted.getCount(), false);
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
|
@ -132,16 +127,23 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
|
|||
PipeNetwork network = PipeNetwork.get(this.world);
|
||||
network.startProfile("terminal_request_item");
|
||||
EquatableItemStack equatable = new EquatableItemStack(stack);
|
||||
this.updateItems();
|
||||
NetworkItem item = this.networkItems.get(equatable);
|
||||
if (item != null) {
|
||||
int remain = stack.getCount();
|
||||
locations:
|
||||
for (NetworkLocation location : item.getLocations()) {
|
||||
for (int slot : location.getStackSlots(stack, ItemEqualityType.NBT)) {
|
||||
ItemStack extracted = location.handler.extractItem(slot, remain, true);
|
||||
if (!extracted.isEmpty()) {
|
||||
this.pendingRequests.add(Triple.of(location, slot, extracted.getCount()));
|
||||
remain -= extracted.getCount();
|
||||
ItemStack inSlot = location.handler.extractItem(slot, Integer.MAX_VALUE, true);
|
||||
if (inSlot.isEmpty())
|
||||
continue;
|
||||
inSlot.shrink(network.getLockedAmount(location.pos, slot));
|
||||
if (inSlot.getCount() > 0) {
|
||||
int extract = Math.min(inSlot.getCount(), remain);
|
||||
NetworkLock lock = new NetworkLock(location, slot, extract);
|
||||
this.pendingRequests.add(lock);
|
||||
network.createNetworkLock(lock);
|
||||
remain -= extract;
|
||||
if (remain <= 0)
|
||||
break locations;
|
||||
}
|
||||
|
|
|
@ -1,19 +1,74 @@
|
|||
package de.ellpeck.prettypipes.terminal.containers;
|
||||
|
||||
import de.ellpeck.prettypipes.Utility;
|
||||
import de.ellpeck.prettypipes.terminal.CraftingTerminalTileEntity;
|
||||
import de.ellpeck.prettypipes.terminal.ItemTerminalTileEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.inventory.CraftResultInventory;
|
||||
import net.minecraft.inventory.CraftingInventory;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.container.ContainerType;
|
||||
import net.minecraft.inventory.container.CraftingResultSlot;
|
||||
import net.minecraft.inventory.container.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.ICraftingRecipe;
|
||||
import net.minecraft.item.crafting.IRecipeType;
|
||||
import net.minecraft.network.play.server.SSetSlotPacket;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.items.SlotItemHandler;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Optional;
|
||||
|
||||
public class CraftingTerminalContainer extends ItemTerminalContainer {
|
||||
|
||||
public CraftingInventory craftInventory;
|
||||
public CraftResultInventory craftResult;
|
||||
private final PlayerEntity player;
|
||||
|
||||
public CraftingTerminalContainer(@Nullable ContainerType<?> type, int id, PlayerEntity player, BlockPos pos) {
|
||||
super(type, id, player, pos);
|
||||
this.player = player;
|
||||
this.onCraftMatrixChanged(this.craftInventory);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addOwnSlots(PlayerEntity player) {
|
||||
this.craftInventory = new WrappedCraftingInventory(this.getTile().craftItems, this, 3, 3);
|
||||
this.craftResult = new CraftResultInventory();
|
||||
this.addSlot(new CraftingResultSlot(player, this.craftInventory, this.craftResult, 0, 25, 77));
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int j = 0; j < 3; j++)
|
||||
this.addSlot(new Slot(this.craftInventory, j + i * 3, 7 + j * 18, 18 + i * 18));
|
||||
super.addOwnSlots(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCraftMatrixChanged(IInventory inventoryIn) {
|
||||
if (!this.player.world.isRemote) {
|
||||
ItemStack ret = ItemStack.EMPTY;
|
||||
Optional<ICraftingRecipe> optional = this.player.world.getServer().getRecipeManager().getRecipe(IRecipeType.CRAFTING, this.craftInventory, this.player.world);
|
||||
if (optional.isPresent())
|
||||
ret = optional.get().getCraftingResult(this.craftInventory);
|
||||
this.craftResult.setInventorySlotContents(0, ret);
|
||||
((ServerPlayerEntity) this.player).connection.sendPacket(new SSetSlotPacket(this.windowId, 0, ret));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack transferStackInSlot(PlayerEntity player, int slotIndex) {
|
||||
return Utility.transferStackInSlot(this, this::mergeItemStack, player, slotIndex, stack -> Pair.of(6 + 10, 12 + 10));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSlotXOffset() {
|
||||
return 65;
|
||||
}
|
||||
|
||||
protected CraftingTerminalTileEntity getTile() {
|
||||
return (CraftingTerminalTileEntity) this.tile;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,49 @@
|
|||
package de.ellpeck.prettypipes.terminal.containers;
|
||||
|
||||
import de.ellpeck.prettypipes.PrettyPipes;
|
||||
import de.ellpeck.prettypipes.packets.PacketHandler;
|
||||
import de.ellpeck.prettypipes.packets.PacketRequest;
|
||||
import de.ellpeck.prettypipes.terminal.CraftingTerminalTileEntity;
|
||||
import net.minecraft.client.gui.widget.Widget;
|
||||
import net.minecraft.client.gui.widget.button.Button;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
public class CraftingTerminalGui extends ItemTerminalGui {
|
||||
private static final ResourceLocation TEXTURE = new ResourceLocation(PrettyPipes.ID, "textures/gui/crafting_terminal.png");
|
||||
private Button requestButton;
|
||||
|
||||
public CraftingTerminalGui(ItemTerminalContainer screenContainer, PlayerInventory inv, ITextComponent titleIn) {
|
||||
super(screenContainer, inv, titleIn);
|
||||
this.xSize = 256;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
super.init();
|
||||
this.requestButton = this.addButton(new Button(this.guiLeft + 8, this.guiTop + 100, 50, 20, I18n.format("info." + PrettyPipes.ID + ".request"), button -> {
|
||||
CraftingTerminalTileEntity tile = this.getCraftingContainer().getTile();
|
||||
for (int i = 0; i < tile.craftItems.getSlots(); i++) {
|
||||
ItemStack stack = tile.getRequestedCraftItem(i);
|
||||
if (stack.isEmpty())
|
||||
continue;
|
||||
stack = stack.copy();
|
||||
stack.setCount(1);
|
||||
PacketHandler.sendToServer(new PacketRequest(this.container.tile.getPos(), stack, 1));
|
||||
}
|
||||
}));
|
||||
this.requestButton.active = !this.getCraftingContainer().craftInventory.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
this.requestButton.active = !this.getCraftingContainer().craftInventory.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceLocation getTexture() {
|
||||
return TEXTURE;
|
||||
|
@ -23,4 +53,8 @@ public class CraftingTerminalGui extends ItemTerminalGui {
|
|||
protected int getXOffset() {
|
||||
return 65;
|
||||
}
|
||||
|
||||
protected CraftingTerminalContainer getCraftingContainer() {
|
||||
return (CraftingTerminalContainer) this.container;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,12 +31,9 @@ public class ItemTerminalContainer extends Container {
|
|||
super(type, id);
|
||||
this.tile = Utility.getTileEntity(ItemTerminalTileEntity.class, player.world, pos);
|
||||
|
||||
int off = this.getSlotXOffset();
|
||||
for (int i = 0; i < 6; i++)
|
||||
this.addSlot(new SlotItemHandler(this.tile.items, i, 8 + off + i % 3 * 18, 102 + i / 3 * 18));
|
||||
for (int i = 0; i < 6; i++)
|
||||
this.addSlot(new SlotItemHandler(this.tile.items, i + 6, 116 + off + i % 3 * 18, 102 + i / 3 * 18));
|
||||
this.addOwnSlots(player);
|
||||
|
||||
int off = this.getSlotXOffset();
|
||||
for (int l = 0; l < 3; ++l)
|
||||
for (int j1 = 0; j1 < 9; ++j1)
|
||||
this.addSlot(new Slot(player.inventory, j1 + l * 9 + 9, 8 + off + j1 * 18, 154 + l * 18));
|
||||
|
@ -44,15 +41,21 @@ public class ItemTerminalContainer extends Container {
|
|||
this.addSlot(new Slot(player.inventory, i1, 8 + off + i1 * 18, 212));
|
||||
}
|
||||
|
||||
protected void addOwnSlots(PlayerEntity player) {
|
||||
int off = this.getSlotXOffset();
|
||||
for (int i = 0; i < 6; i++)
|
||||
this.addSlot(new SlotItemHandler(this.tile.items, i, 8 + off + i % 3 * 18, 102 + i / 3 * 18));
|
||||
for (int i = 0; i < 6; i++)
|
||||
this.addSlot(new SlotItemHandler(this.tile.items, i + 6, 116 + off + i % 3 * 18, 102 + i / 3 * 18));
|
||||
}
|
||||
|
||||
protected int getSlotXOffset() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack transferStackInSlot(PlayerEntity player, int slotIndex) {
|
||||
return Utility.transferStackInSlot(this, this::mergeItemStack, player, slotIndex, stack -> {
|
||||
return Pair.of(6, 12);
|
||||
});
|
||||
return Utility.transferStackInSlot(this, this::mergeItemStack, player, slotIndex, stack -> Pair.of(6, 12));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
package de.ellpeck.prettypipes.terminal.containers;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.CraftingInventory;
|
||||
import net.minecraft.inventory.ItemStackHelper;
|
||||
import net.minecraft.inventory.container.Container;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.RecipeItemHelper;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
|
||||
public class WrappedCraftingInventory extends CraftingInventory {
|
||||
|
||||
private final ItemStackHandler items;
|
||||
private final Container eventHandler;
|
||||
|
||||
public WrappedCraftingInventory(ItemStackHandler items, Container eventHandlerIn, int width, int height) {
|
||||
super(eventHandlerIn, width, height);
|
||||
this.eventHandler = eventHandlerIn;
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSizeInventory() {
|
||||
return this.items.getSlots();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
for (int i = 0; i < this.items.getSlots(); i++) {
|
||||
if (!this.items.getStackInSlot(i).isEmpty())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int index) {
|
||||
return this.items.getStackInSlot(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeStackFromSlot(int index) {
|
||||
ItemStack before = this.items.getStackInSlot(index);
|
||||
this.items.setStackInSlot(index, ItemStack.EMPTY);
|
||||
return before;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack decrStackSize(int index, int count) {
|
||||
ItemStack slotStack = this.items.getStackInSlot(index);
|
||||
ItemStack ret = !slotStack.isEmpty() && count > 0 ? slotStack.split(count) : ItemStack.EMPTY;
|
||||
if (!ret.isEmpty())
|
||||
this.eventHandler.onCraftMatrixChanged(this);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInventorySlotContents(int index, ItemStack stack) {
|
||||
this.items.setStackInSlot(index, stack);
|
||||
this.eventHandler.onCraftMatrixChanged(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
for (int i = 0; i < this.items.getSlots(); i++)
|
||||
this.items.setStackInSlot(i, ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillStackedContents(RecipeItemHelper helper) {
|
||||
for (int i = 0; i < this.items.getSlots(); i++)
|
||||
helper.accountPlainStack(this.items.getStackInSlot(i));
|
||||
}
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Loading…
Reference in a new issue