mirror of
https://github.com/Ellpeck/PrettyPipes.git
synced 2024-11-22 19:58:35 +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) {
|
} else if (id == 1 && this.canPopulateFromInventories) {
|
||||||
// populate filter from inventories
|
// populate filter from inventories
|
||||||
for (Direction direction : Direction.values()) {
|
for (Direction direction : Direction.values()) {
|
||||||
IItemHandler handler = this.pipe.getItemHandler(direction, false);
|
IItemHandler handler = this.pipe.getItemHandler(direction, null);
|
||||||
if (handler == null)
|
if (handler == null)
|
||||||
continue;
|
continue;
|
||||||
for (int i = 0; i < handler.getSlots(); i++) {
|
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;
|
package de.ellpeck.prettypipes.network;
|
||||||
|
|
||||||
import de.ellpeck.prettypipes.Utility;
|
import de.ellpeck.prettypipes.Utility;
|
||||||
|
import de.ellpeck.prettypipes.pipe.IPipeConnectable;
|
||||||
import de.ellpeck.prettypipes.pipe.PipeTileEntity;
|
import de.ellpeck.prettypipes.pipe.PipeTileEntity;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.ILiquidContainer;
|
import net.minecraft.block.ILiquidContainer;
|
||||||
|
@ -172,10 +173,13 @@ public class PipeItem implements INBTSerializable<CompoundNBT>, ILiquidContainer
|
||||||
|
|
||||||
private ItemStack store(PipeTileEntity currPipe) {
|
private ItemStack store(PipeTileEntity currPipe) {
|
||||||
Direction dir = Utility.getDirectionFromOffset(this.destInventory, this.getDestPipe());
|
Direction dir = Utility.getDirectionFromOffset(this.destInventory, this.getDestPipe());
|
||||||
IItemHandler handler = currPipe.getItemHandler(dir, true);
|
IPipeConnectable connectable = currPipe.getPipeConnectable(dir);
|
||||||
if (handler == null)
|
if (connectable != null)
|
||||||
return this.stack;
|
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 ItemHandlerHelper.insertItemStacked(handler, this.stack, false);
|
||||||
|
return this.stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PipeTileEntity getNextTile(PipeTileEntity currPipe, boolean progress) {
|
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, List<BlockPos>> nodeToConnectedNodes = new HashMap<>();
|
||||||
private final Map<BlockPos, PipeTileEntity> tileCache = new HashMap<>();
|
private final Map<BlockPos, PipeTileEntity> tileCache = new HashMap<>();
|
||||||
private final ListMultimap<BlockPos, PipeItem> pipeItems = ArrayListMultimap.create();
|
private final ListMultimap<BlockPos, PipeItem> pipeItems = ArrayListMultimap.create();
|
||||||
|
private final ListMultimap<BlockPos, NetworkLock> networkLocks = ArrayListMultimap.create();
|
||||||
private final World world;
|
private final World world;
|
||||||
|
|
||||||
public PipeNetwork(World world) {
|
public PipeNetwork(World world) {
|
||||||
|
@ -189,7 +190,7 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
|
||||||
if (!pipe.canNetworkSee())
|
if (!pipe.canNetworkSee())
|
||||||
continue;
|
continue;
|
||||||
for (Direction dir : Direction.values()) {
|
for (Direction dir : Direction.values()) {
|
||||||
IItemHandler handler = pipe.getItemHandler(dir, false);
|
IItemHandler handler = pipe.getItemHandler(dir, null);
|
||||||
if (handler == null)
|
if (handler == null)
|
||||||
continue;
|
continue;
|
||||||
// check if this handler already exists (double-connected pipes, double chests etc.)
|
// 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;
|
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) {
|
private void refreshNode(BlockPos pos, BlockState state) {
|
||||||
this.startProfile("refresh_node");
|
this.startProfile("refresh_node");
|
||||||
this.graph.removeAllEdges(new ArrayList<>(this.graph.edgesOf(pos)));
|
this.graph.removeAllEdges(new ArrayList<>(this.graph.edgesOf(pos)));
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package de.ellpeck.prettypipes.pipe;
|
package de.ellpeck.prettypipes.pipe;
|
||||||
|
|
||||||
|
import de.ellpeck.prettypipes.network.PipeItem;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
@ -8,9 +10,13 @@ import net.minecraftforge.items.IItemHandler;
|
||||||
|
|
||||||
public interface IPipeConnectable {
|
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;
|
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);
|
PipeTileEntity tile = Utility.getTileEntity(PipeTileEntity.class, worldIn, pos);
|
||||||
if (tile == null)
|
if (tile == null)
|
||||||
return ActionResultType.PASS;
|
return ActionResultType.PASS;
|
||||||
if (!tile.isConnectedInventory(false))
|
if (!tile.isConnectedInventory())
|
||||||
return ActionResultType.PASS;
|
return ActionResultType.PASS;
|
||||||
if (!worldIn.isRemote)
|
if (!worldIn.isRemote)
|
||||||
NetworkHooks.openGui((ServerPlayerEntity) player, tile, pos);
|
NetworkHooks.openGui((ServerPlayerEntity) player, tile, pos);
|
||||||
|
@ -161,7 +161,7 @@ public class PipeBlock extends ContainerBlock implements IPipeConnectable {
|
||||||
BlockState offState = world.getBlockState(offset);
|
BlockState offState = world.getBlockState(offset);
|
||||||
Block block = offState.getBlock();
|
Block block = offState.getBlock();
|
||||||
if (block instanceof IPipeConnectable)
|
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);
|
TileEntity tile = world.getTileEntity(offset);
|
||||||
if (tile != null) {
|
if (tile != null) {
|
||||||
IItemHandler handler = tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, direction.getOpposite()).orElse(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) {
|
public static void onStateChanged(World world, BlockPos pos, BlockState newState) {
|
||||||
PipeTileEntity tile = Utility.getTileEntity(PipeTileEntity.class, world, pos);
|
PipeTileEntity tile = Utility.getTileEntity(PipeTileEntity.class, world, pos);
|
||||||
if (tile != null && !tile.isConnectedInventory(false))
|
if (tile != null && !tile.isConnectedInventory())
|
||||||
Utility.dropInventory(tile, tile.modules);
|
Utility.dropInventory(tile, tile.modules);
|
||||||
|
|
||||||
PipeNetwork network = PipeNetwork.get(world);
|
PipeNetwork network = PipeNetwork.get(world);
|
||||||
|
@ -252,8 +252,9 @@ public class PipeBlock extends ContainerBlock implements IPipeConnectable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConnectionType getConnectionType(World world, BlockPos pos, BlockState state, BlockPos pipePos, Direction direction) {
|
public ConnectionType getConnectionType(World world, BlockPos pipePos, Direction direction) {
|
||||||
if (state.get(DIRECTIONS.get(direction)) == ConnectionType.BLOCKED)
|
BlockState state = world.getBlockState(pipePos.offset(direction));
|
||||||
|
if (state.get(DIRECTIONS.get(direction.getOpposite())) == ConnectionType.BLOCKED)
|
||||||
return ConnectionType.BLOCKED;
|
return ConnectionType.BLOCKED;
|
||||||
return ConnectionType.CONNECTED;
|
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)))
|
if (!force && this.streamModules().anyMatch(m -> !m.getRight().canAcceptItem(m.getLeft(), this, stack)))
|
||||||
return null;
|
return null;
|
||||||
for (Direction dir : Direction.values()) {
|
for (Direction dir : Direction.values()) {
|
||||||
IItemHandler handler = this.getItemHandler(dir, force);
|
IItemHandler handler = this.getItemHandler(dir, null);
|
||||||
if (handler == null)
|
if (handler == null)
|
||||||
continue;
|
continue;
|
||||||
if (!ItemHandlerHelper.insertItem(handler, stack, true).isEmpty())
|
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));
|
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))
|
if (!this.isConnected(dir))
|
||||||
return null;
|
return null;
|
||||||
BlockPos pos = this.pos.offset(dir);
|
BlockPos pos = this.pos.offset(dir);
|
||||||
|
@ -208,21 +208,25 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
||||||
if (handler != null)
|
if (handler != null)
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
BlockState state = this.world.getBlockState(pos);
|
IPipeConnectable connectable = this.getPipeConnectable(dir);
|
||||||
if (state.getBlock() instanceof IPipeConnectable) {
|
if (connectable != null)
|
||||||
IItemHandler handler = ((IPipeConnectable) state.getBlock()).getItemHandler(this.world, pos, state, this.pos, dir, force);
|
return connectable.getItemHandler(this.world, this.pos, dir, item);
|
||||||
if (handler != null)
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isConnectedInventory(Direction dir, boolean force) {
|
public IPipeConnectable getPipeConnectable(Direction dir) {
|
||||||
return this.getItemHandler(dir, force) != null;
|
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) {
|
public boolean isConnectedInventory(Direction dir) {
|
||||||
return Arrays.stream(Direction.values()).anyMatch(dir -> this.isConnectedInventory(dir, force));
|
return this.getItemHandler(dir, null) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isConnectedInventory() {
|
||||||
|
return Arrays.stream(Direction.values()).anyMatch(this::isConnectedInventory);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canNetworkSee() {
|
public boolean canNetworkSee() {
|
||||||
|
|
|
@ -39,7 +39,7 @@ public class ExtractionModuleItem extends ModuleItem {
|
||||||
|
|
||||||
PipeNetwork network = PipeNetwork.get(tile.getWorld());
|
PipeNetwork network = PipeNetwork.get(tile.getWorld());
|
||||||
for (Direction dir : Direction.values()) {
|
for (Direction dir : Direction.values()) {
|
||||||
IItemHandler handler = tile.getItemHandler(dir, false);
|
IItemHandler handler = tile.getItemHandler(dir, null);
|
||||||
if (handler == null)
|
if (handler == null)
|
||||||
continue;
|
continue;
|
||||||
for (int j = 0; j < handler.getSlots(); j++) {
|
for (int j = 0; j < handler.getSlots(); j++) {
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
package de.ellpeck.prettypipes.terminal;
|
package de.ellpeck.prettypipes.terminal;
|
||||||
|
|
||||||
import de.ellpeck.prettypipes.terminal.containers.ItemTerminalGui;
|
import de.ellpeck.prettypipes.Utility;
|
||||||
import net.minecraft.block.ContainerBlock;
|
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.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.IBlockReader;
|
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;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
@ -14,4 +21,29 @@ public class CraftingTerminalBlock extends ItemTerminalBlock {
|
||||||
public TileEntity createNewTileEntity(IBlockReader worldIn) {
|
public TileEntity createNewTileEntity(IBlockReader worldIn) {
|
||||||
return new CraftingTerminalTileEntity();
|
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.PlayerEntity;
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
import net.minecraft.inventory.container.Container;
|
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.ITextComponent;
|
||||||
import net.minecraft.util.text.TranslationTextComponent;
|
import net.minecraft.util.text.TranslationTextComponent;
|
||||||
|
import net.minecraftforge.items.ItemStackHandler;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class CraftingTerminalTileEntity extends ItemTerminalTileEntity {
|
public class CraftingTerminalTileEntity extends ItemTerminalTileEntity {
|
||||||
|
|
||||||
|
public final ItemStackHandler craftItems = new ItemStackHandler(9);
|
||||||
|
|
||||||
public CraftingTerminalTileEntity() {
|
public CraftingTerminalTileEntity() {
|
||||||
super(Registry.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
|
@Override
|
||||||
public ITextComponent getDisplayName() {
|
public ITextComponent getDisplayName() {
|
||||||
return new TranslationTextComponent("container." + PrettyPipes.ID + ".crafting_terminal");
|
return new TranslationTextComponent("container." + PrettyPipes.ID + ".crafting_terminal");
|
||||||
|
|
|
@ -25,6 +25,7 @@ import net.minecraft.world.IBlockReader;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.fml.network.NetworkHooks;
|
import net.minecraftforge.fml.network.NetworkHooks;
|
||||||
import net.minecraftforge.items.IItemHandler;
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
import net.minecraftforge.items.ItemHandlerHelper;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -63,18 +64,17 @@ public class ItemTerminalBlock extends ContainerBlock implements IPipeConnectabl
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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;
|
return ConnectionType.CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IItemHandler getItemHandler(World world, BlockPos pos, BlockState state, BlockPos pipePos, Direction direction, boolean force) {
|
public ItemStack insertItem(World world, BlockPos pipePos, Direction direction, PipeItem item) {
|
||||||
if (force) {
|
BlockPos pos = pipePos.offset(direction);
|
||||||
ItemTerminalTileEntity tile = Utility.getTileEntity(ItemTerminalTileEntity.class, world, pos);
|
ItemTerminalTileEntity tile = Utility.getTileEntity(ItemTerminalTileEntity.class, world, pos);
|
||||||
if (tile != null)
|
if (tile != null)
|
||||||
return tile.items;
|
return ItemHandlerHelper.insertItemStacked(tile.items, item.stack, false);
|
||||||
}
|
return item.stack;
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -6,10 +6,7 @@ import de.ellpeck.prettypipes.Utility;
|
||||||
import de.ellpeck.prettypipes.misc.EquatableItemStack;
|
import de.ellpeck.prettypipes.misc.EquatableItemStack;
|
||||||
import de.ellpeck.prettypipes.misc.ItemEqualityType;
|
import de.ellpeck.prettypipes.misc.ItemEqualityType;
|
||||||
import de.ellpeck.prettypipes.misc.ItemOrder;
|
import de.ellpeck.prettypipes.misc.ItemOrder;
|
||||||
import de.ellpeck.prettypipes.network.NetworkItem;
|
import de.ellpeck.prettypipes.network.*;
|
||||||
import de.ellpeck.prettypipes.network.NetworkLocation;
|
|
||||||
import de.ellpeck.prettypipes.network.PipeItem;
|
|
||||||
import de.ellpeck.prettypipes.network.PipeNetwork;
|
|
||||||
import de.ellpeck.prettypipes.packets.PacketHandler;
|
import de.ellpeck.prettypipes.packets.PacketHandler;
|
||||||
import de.ellpeck.prettypipes.packets.PacketNetworkItems;
|
import de.ellpeck.prettypipes.packets.PacketNetworkItems;
|
||||||
import de.ellpeck.prettypipes.pipe.PipeTileEntity;
|
import de.ellpeck.prettypipes.pipe.PipeTileEntity;
|
||||||
|
@ -50,7 +47,7 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
public Map<EquatableItemStack, NetworkItem> networkItems;
|
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) {
|
protected ItemTerminalTileEntity(TileEntityType<?> tileEntityTypeIn) {
|
||||||
super(tileEntityTypeIn);
|
super(tileEntityTypeIn);
|
||||||
|
@ -82,13 +79,11 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.pendingRequests.isEmpty()) {
|
if (!this.pendingRequests.isEmpty()) {
|
||||||
Triple<NetworkLocation, Integer, Integer> request = this.pendingRequests.remove();
|
NetworkLock request = this.pendingRequests.remove();
|
||||||
NetworkLocation location = request.getLeft();
|
network.resolveNetworkLock(request);
|
||||||
int slot = request.getMiddle();
|
ItemStack extracted = request.location.handler.extractItem(request.slot, request.amount, true);
|
||||||
int amount = request.getRight();
|
if (network.routeItemToLocation(request.location.pipePos, request.location.pos, pipe.getPos(), this.pos, speed -> new PipeItem(extracted, speed))) {
|
||||||
ItemStack extracted = location.handler.extractItem(slot, amount, true);
|
request.location.handler.extractItem(request.slot, extracted.getCount(), false);
|
||||||
if (network.routeItemToLocation(location.pipePos, location.pos, pipe.getPos(), this.pos, speed -> new PipeItem(extracted, speed))) {
|
|
||||||
location.handler.extractItem(slot, extracted.getCount(), false);
|
|
||||||
update = true;
|
update = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,16 +127,23 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
|
||||||
PipeNetwork network = PipeNetwork.get(this.world);
|
PipeNetwork network = PipeNetwork.get(this.world);
|
||||||
network.startProfile("terminal_request_item");
|
network.startProfile("terminal_request_item");
|
||||||
EquatableItemStack equatable = new EquatableItemStack(stack);
|
EquatableItemStack equatable = new EquatableItemStack(stack);
|
||||||
|
this.updateItems();
|
||||||
NetworkItem item = this.networkItems.get(equatable);
|
NetworkItem item = this.networkItems.get(equatable);
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
int remain = stack.getCount();
|
int remain = stack.getCount();
|
||||||
locations:
|
locations:
|
||||||
for (NetworkLocation location : item.getLocations()) {
|
for (NetworkLocation location : item.getLocations()) {
|
||||||
for (int slot : location.getStackSlots(stack, ItemEqualityType.NBT)) {
|
for (int slot : location.getStackSlots(stack, ItemEqualityType.NBT)) {
|
||||||
ItemStack extracted = location.handler.extractItem(slot, remain, true);
|
ItemStack inSlot = location.handler.extractItem(slot, Integer.MAX_VALUE, true);
|
||||||
if (!extracted.isEmpty()) {
|
if (inSlot.isEmpty())
|
||||||
this.pendingRequests.add(Triple.of(location, slot, extracted.getCount()));
|
continue;
|
||||||
remain -= extracted.getCount();
|
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)
|
if (remain <= 0)
|
||||||
break locations;
|
break locations;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,74 @@
|
||||||
package de.ellpeck.prettypipes.terminal.containers;
|
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.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.ContainerType;
|
||||||
|
import net.minecraft.inventory.container.CraftingResultSlot;
|
||||||
import net.minecraft.inventory.container.Slot;
|
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.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 javax.annotation.Nullable;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public class CraftingTerminalContainer extends ItemTerminalContainer {
|
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) {
|
public CraftingTerminalContainer(@Nullable ContainerType<?> type, int id, PlayerEntity player, BlockPos pos) {
|
||||||
super(type, id, player, 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
|
@Override
|
||||||
protected int getSlotXOffset() {
|
protected int getSlotXOffset() {
|
||||||
return 65;
|
return 65;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected CraftingTerminalTileEntity getTile() {
|
||||||
|
return (CraftingTerminalTileEntity) this.tile;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,49 @@
|
||||||
package de.ellpeck.prettypipes.terminal.containers;
|
package de.ellpeck.prettypipes.terminal.containers;
|
||||||
|
|
||||||
import de.ellpeck.prettypipes.PrettyPipes;
|
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.Widget;
|
||||||
|
import net.minecraft.client.gui.widget.button.Button;
|
||||||
|
import net.minecraft.client.resources.I18n;
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.text.ITextComponent;
|
import net.minecraft.util.text.ITextComponent;
|
||||||
|
|
||||||
public class CraftingTerminalGui extends ItemTerminalGui {
|
public class CraftingTerminalGui extends ItemTerminalGui {
|
||||||
private static final ResourceLocation TEXTURE = new ResourceLocation(PrettyPipes.ID, "textures/gui/crafting_terminal.png");
|
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) {
|
public CraftingTerminalGui(ItemTerminalContainer screenContainer, PlayerInventory inv, ITextComponent titleIn) {
|
||||||
super(screenContainer, inv, titleIn);
|
super(screenContainer, inv, titleIn);
|
||||||
this.xSize = 256;
|
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
|
@Override
|
||||||
protected ResourceLocation getTexture() {
|
protected ResourceLocation getTexture() {
|
||||||
return TEXTURE;
|
return TEXTURE;
|
||||||
|
@ -23,4 +53,8 @@ public class CraftingTerminalGui extends ItemTerminalGui {
|
||||||
protected int getXOffset() {
|
protected int getXOffset() {
|
||||||
return 65;
|
return 65;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected CraftingTerminalContainer getCraftingContainer() {
|
||||||
|
return (CraftingTerminalContainer) this.container;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,12 +31,9 @@ public class ItemTerminalContainer extends Container {
|
||||||
super(type, id);
|
super(type, id);
|
||||||
this.tile = Utility.getTileEntity(ItemTerminalTileEntity.class, player.world, pos);
|
this.tile = Utility.getTileEntity(ItemTerminalTileEntity.class, player.world, pos);
|
||||||
|
|
||||||
int off = this.getSlotXOffset();
|
this.addOwnSlots(player);
|
||||||
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));
|
|
||||||
|
|
||||||
|
int off = this.getSlotXOffset();
|
||||||
for (int l = 0; l < 3; ++l)
|
for (int l = 0; l < 3; ++l)
|
||||||
for (int j1 = 0; j1 < 9; ++j1)
|
for (int j1 = 0; j1 < 9; ++j1)
|
||||||
this.addSlot(new Slot(player.inventory, j1 + l * 9 + 9, 8 + off + j1 * 18, 154 + l * 18));
|
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));
|
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() {
|
protected int getSlotXOffset() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemStack transferStackInSlot(PlayerEntity player, int slotIndex) {
|
public ItemStack transferStackInSlot(PlayerEntity player, int slotIndex) {
|
||||||
return Utility.transferStackInSlot(this, this::mergeItemStack, player, slotIndex, stack -> {
|
return Utility.transferStackInSlot(this, this::mergeItemStack, player, slotIndex, stack -> Pair.of(6, 12));
|
||||||
return Pair.of(6, 12);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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