mirror of
https://github.com/Ellpeck/PrettyPipes.git
synced 2024-11-26 13:28:33 +01:00
IT'S DONE
This commit is contained in:
parent
ae74359ed5
commit
fe3d4380f3
18 changed files with 299 additions and 93 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);
|
IItemHandler handler = this.pipe.getItemHandler(direction, false);
|
||||||
if (handler == null)
|
if (handler == null)
|
||||||
continue;
|
continue;
|
||||||
for (int i = 0; i < handler.getSlots(); i++) {
|
for (int i = 0; i < handler.getSlots(); i++) {
|
||||||
|
|
|
@ -18,29 +18,23 @@ import java.util.List;
|
||||||
public class ItemTerminalWidget extends Widget {
|
public class ItemTerminalWidget extends Widget {
|
||||||
|
|
||||||
private static final ResourceLocation FONT = new ResourceLocation(PrettyPipes.ID, "unicode");
|
private static final ResourceLocation FONT = new ResourceLocation(PrettyPipes.ID, "unicode");
|
||||||
private final ItemStack stack;
|
|
||||||
private final ItemTerminalGui screen;
|
private final ItemTerminalGui screen;
|
||||||
public final int gridX;
|
public final int gridX;
|
||||||
public final int gridY;
|
public final int gridY;
|
||||||
public boolean hidden;
|
public boolean selected;
|
||||||
|
public ItemStack stack = ItemStack.EMPTY;
|
||||||
|
|
||||||
public ItemTerminalWidget(int xIn, int yIn, int gridX, int gridY, ItemStack stack, ItemTerminalGui screen) {
|
public ItemTerminalWidget(int xIn, int yIn, int gridX, int gridY, ItemTerminalGui screen) {
|
||||||
super(xIn, yIn, 16, 16, stack.getDisplayName().getFormattedText());
|
super(xIn, yIn, 16, 16, "");
|
||||||
this.gridX = gridX;
|
this.gridX = gridX;
|
||||||
this.gridY = gridY;
|
this.gridY = gridY;
|
||||||
this.stack = stack;
|
|
||||||
this.screen = screen;
|
this.screen = screen;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean clicked(double x, double y) {
|
public void onClick(double x, double y) {
|
||||||
return false;
|
this.screen.streamWidgets().forEach(w -> w.selected = false);
|
||||||
}
|
this.selected = true;
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(int mouseX, int mouseY, float partialTicks) {
|
|
||||||
if (!this.hidden)
|
|
||||||
super.render(mouseX, mouseY, partialTicks);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -49,6 +43,8 @@ public class ItemTerminalWidget extends Widget {
|
||||||
ItemRenderer renderer = mc.getItemRenderer();
|
ItemRenderer renderer = mc.getItemRenderer();
|
||||||
this.setBlitOffset(100);
|
this.setBlitOffset(100);
|
||||||
renderer.zLevel = 100;
|
renderer.zLevel = 100;
|
||||||
|
if (this.selected)
|
||||||
|
fill(this.x, this.y, this.x + 16, this.y + 16, -2130706433);
|
||||||
RenderSystem.enableDepthTest();
|
RenderSystem.enableDepthTest();
|
||||||
renderer.renderItemAndEffectIntoGUI(mc.player, this.stack, this.x, this.y);
|
renderer.renderItemAndEffectIntoGUI(mc.player, this.stack, this.x, this.y);
|
||||||
int amount = this.stack.getCount();
|
int amount = this.stack.getCount();
|
||||||
|
@ -69,7 +65,7 @@ public class ItemTerminalWidget extends Widget {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderToolTip(int mouseX, int mouseY) {
|
public void renderToolTip(int mouseX, int mouseY) {
|
||||||
if (this.isHovered()) {
|
if (this.visible && this.isHovered()) {
|
||||||
FontRenderer font = this.stack.getItem().getFontRenderer(this.stack);
|
FontRenderer font = this.stack.getItem().getFontRenderer(this.stack);
|
||||||
if (font == null)
|
if (font == null)
|
||||||
font = this.screen.getMinecraft().fontRenderer;
|
font = this.screen.getMinecraft().fontRenderer;
|
||||||
|
|
|
@ -3,14 +3,11 @@ package de.ellpeck.prettypipes.network;
|
||||||
import de.ellpeck.prettypipes.misc.EquatableItemStack;
|
import de.ellpeck.prettypipes.misc.EquatableItemStack;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class NetworkItem {
|
public class NetworkItem {
|
||||||
|
|
||||||
private final Set<NetworkLocation> locations = new HashSet<>();
|
private final List<NetworkLocation> locations = new ArrayList<>();
|
||||||
private final EquatableItemStack item;
|
private final EquatableItemStack item;
|
||||||
private int amount;
|
private int amount;
|
||||||
|
|
||||||
|
@ -19,8 +16,13 @@ public class NetworkItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(NetworkLocation location, ItemStack stack) {
|
public void add(NetworkLocation location, ItemStack stack) {
|
||||||
this.locations.add(location);
|
|
||||||
this.amount += stack.getCount();
|
this.amount += stack.getCount();
|
||||||
|
if (!this.locations.contains(location))
|
||||||
|
this.locations.add(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<NetworkLocation> getLocations() {
|
||||||
|
return this.locations;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemStack asStack() {
|
public ItemStack asStack() {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import net.minecraftforge.items.IItemHandler;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class NetworkLocation {
|
public class NetworkLocation {
|
||||||
|
|
||||||
|
@ -31,14 +32,13 @@ public class NetworkLocation {
|
||||||
this.items.put(slot, stack);
|
this.items.put(slot, stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getStackSlot(ItemStack stack) {
|
public List<Integer> getStackSlots(ItemStack stack) {
|
||||||
if (this.isEmpty())
|
if (this.isEmpty())
|
||||||
return -1;
|
return Collections.emptyList();
|
||||||
for (Map.Entry<Integer, ItemStack> entry : this.items.entrySet()) {
|
return this.items.entrySet().stream()
|
||||||
if (entry.getValue().isItemEqual(stack))
|
.filter(e -> e.getValue().isItemEqual(stack))
|
||||||
return entry.getKey();
|
.map(Map.Entry::getKey)
|
||||||
}
|
.collect(Collectors.toList());
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getItemAmount(ItemStack stack, boolean compareTag) {
|
public int getItemAmount(ItemStack stack, boolean compareTag) {
|
||||||
|
|
|
@ -172,7 +172,7 @@ 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);
|
IItemHandler handler = currPipe.getItemHandler(dir, true);
|
||||||
if (handler == null)
|
if (handler == null)
|
||||||
return this.stack;
|
return this.stack;
|
||||||
return ItemHandlerHelper.insertItemStacked(handler, this.stack, false);
|
return ItemHandlerHelper.insertItemStacked(handler, this.stack, false);
|
||||||
|
|
|
@ -188,7 +188,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);
|
IItemHandler handler = pipe.getItemHandler(dir, false);
|
||||||
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.)
|
||||||
|
|
|
@ -21,6 +21,7 @@ public final class PacketHandler {
|
||||||
network.registerMessage(0, PacketItemEnterPipe.class, PacketItemEnterPipe::toBytes, PacketItemEnterPipe::fromBytes, PacketItemEnterPipe::onMessage);
|
network.registerMessage(0, PacketItemEnterPipe.class, PacketItemEnterPipe::toBytes, PacketItemEnterPipe::fromBytes, PacketItemEnterPipe::onMessage);
|
||||||
network.registerMessage(1, PacketButton.class, PacketButton::toBytes, PacketButton::fromBytes, PacketButton::onMessage);
|
network.registerMessage(1, PacketButton.class, PacketButton::toBytes, PacketButton::fromBytes, PacketButton::onMessage);
|
||||||
network.registerMessage(2, PacketNetworkItems.class, PacketNetworkItems::toBytes, PacketNetworkItems::fromBytes, PacketNetworkItems::onMessage);
|
network.registerMessage(2, PacketNetworkItems.class, PacketNetworkItems::toBytes, PacketNetworkItems::fromBytes, PacketNetworkItems::onMessage);
|
||||||
|
network.registerMessage(3, PacketRequest.class, PacketRequest::toBytes, PacketRequest::fromBytes, PacketRequest::onMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendToAllLoaded(World world, BlockPos pos, Object message) {
|
public static void sendToAllLoaded(World world, BlockPos pos, Object message) {
|
||||||
|
|
|
@ -44,7 +44,9 @@ public class PacketNetworkItems {
|
||||||
public static void toBytes(PacketNetworkItems packet, PacketBuffer buf) {
|
public static void toBytes(PacketNetworkItems packet, PacketBuffer buf) {
|
||||||
buf.writeVarInt(packet.items.size());
|
buf.writeVarInt(packet.items.size());
|
||||||
for (ItemStack stack : packet.items) {
|
for (ItemStack stack : packet.items) {
|
||||||
buf.writeItemStack(stack);
|
ItemStack copy = stack.copy();
|
||||||
|
copy.setCount(1);
|
||||||
|
buf.writeItemStack(copy);
|
||||||
buf.writeVarInt(stack.getCount());
|
buf.writeVarInt(stack.getCount());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
package de.ellpeck.prettypipes.packets;
|
||||||
|
|
||||||
|
import de.ellpeck.prettypipes.Utility;
|
||||||
|
import de.ellpeck.prettypipes.terminal.ItemTerminalTileEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraftforge.fml.network.NetworkEvent;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class PacketRequest {
|
||||||
|
|
||||||
|
private BlockPos pos;
|
||||||
|
private ItemStack stack;
|
||||||
|
private int amount;
|
||||||
|
|
||||||
|
public PacketRequest(BlockPos pos, ItemStack stack, int amount) {
|
||||||
|
this.pos = pos;
|
||||||
|
this.stack = stack;
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PacketRequest() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PacketRequest fromBytes(PacketBuffer buf) {
|
||||||
|
PacketRequest packet = new PacketRequest();
|
||||||
|
packet.pos = buf.readBlockPos();
|
||||||
|
packet.stack = buf.readItemStack();
|
||||||
|
packet.amount = buf.readVarInt();
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void toBytes(PacketRequest packet, PacketBuffer buf) {
|
||||||
|
buf.writeBlockPos(packet.pos);
|
||||||
|
buf.writeItemStack(packet.stack);
|
||||||
|
buf.writeVarInt(packet.amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("Convert2Lambda")
|
||||||
|
public static void onMessage(PacketRequest message, Supplier<NetworkEvent.Context> ctx) {
|
||||||
|
ctx.get().enqueueWork(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
PlayerEntity player = ctx.get().getSender();
|
||||||
|
ItemTerminalTileEntity tile = Utility.getTileEntity(ItemTerminalTileEntity.class, player.world, message.pos);
|
||||||
|
message.stack.setCount(message.amount);
|
||||||
|
tile.requestItem(player, message.stack);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ctx.get().setPacketHandled(true);
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,9 +4,13 @@ import net.minecraft.block.BlockState;
|
||||||
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;
|
||||||
|
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 pos, BlockState state, BlockPos pipePos, Direction direction);
|
||||||
|
|
||||||
|
default IItemHandler getItemHandler(World world, BlockPos pos, BlockState state, BlockPos pipePos, Direction direction, boolean force) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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())
|
if (!tile.isConnectedInventory(false))
|
||||||
return ActionResultType.PASS;
|
return ActionResultType.PASS;
|
||||||
if (!worldIn.isRemote)
|
if (!worldIn.isRemote)
|
||||||
NetworkHooks.openGui((ServerPlayerEntity) player, tile, pos);
|
NetworkHooks.openGui((ServerPlayerEntity) player, tile, pos);
|
||||||
|
@ -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())
|
if (tile != null && !tile.isConnectedInventory(false))
|
||||||
Utility.dropInventory(tile, tile.modules);
|
Utility.dropInventory(tile, tile.modules);
|
||||||
|
|
||||||
PipeNetwork network = PipeNetwork.get(world);
|
PipeNetwork network = PipeNetwork.get(world);
|
||||||
|
|
|
@ -133,13 +133,13 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
||||||
return this.getBlockState().get(PipeBlock.DIRECTIONS.get(dir)).isConnected();
|
return this.getBlockState().get(PipeBlock.DIRECTIONS.get(dir)).isConnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockPos getAvailableDestination(ItemStack stack, boolean internal, boolean preventOversending) {
|
public BlockPos getAvailableDestination(ItemStack stack, boolean force, boolean preventOversending) {
|
||||||
if (!this.canWork())
|
if (!this.canWork())
|
||||||
return null;
|
return null;
|
||||||
if (!internal && 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);
|
IItemHandler handler = this.getItemHandler(dir, force);
|
||||||
if (handler == null)
|
if (handler == null)
|
||||||
continue;
|
continue;
|
||||||
if (!ItemHandlerHelper.insertItem(handler, stack, true).isEmpty())
|
if (!ItemHandlerHelper.insertItem(handler, stack, true).isEmpty())
|
||||||
|
@ -185,27 +185,37 @@ 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) {
|
public IItemHandler getItemHandler(Direction dir, boolean force) {
|
||||||
if (!this.isConnected(dir))
|
if (!this.isConnected(dir))
|
||||||
return null;
|
return null;
|
||||||
TileEntity tile = this.world.getTileEntity(this.pos.offset(dir));
|
BlockPos pos = this.pos.offset(dir);
|
||||||
if (tile == null)
|
TileEntity tile = this.world.getTileEntity(pos);
|
||||||
return null;
|
if (tile != null) {
|
||||||
// if we don't do this, then chests get really weird
|
// if we don't do this, then chests get really weird
|
||||||
if (tile instanceof ChestTileEntity) {
|
if (tile instanceof ChestTileEntity) {
|
||||||
BlockState state = this.world.getBlockState(tile.getPos());
|
BlockState state = this.world.getBlockState(tile.getPos());
|
||||||
if (state.getBlock() instanceof ChestBlock)
|
if (state.getBlock() instanceof ChestBlock)
|
||||||
return new InvWrapper(ChestBlock.func_226916_a_((ChestBlock) state.getBlock(), state, this.world, tile.getPos(), true));
|
return new InvWrapper(ChestBlock.func_226916_a_((ChestBlock) state.getBlock(), state, this.world, tile.getPos(), true));
|
||||||
}
|
}
|
||||||
return tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, dir.getOpposite()).orElse(null);
|
IItemHandler handler = tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, dir.getOpposite()).orElse(null);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isConnectedInventory(Direction dir) {
|
public boolean isConnectedInventory(Direction dir, boolean force) {
|
||||||
return this.getItemHandler(dir) != null;
|
return this.getItemHandler(dir, force) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isConnectedInventory() {
|
public boolean isConnectedInventory(boolean force) {
|
||||||
return Arrays.stream(Direction.values()).anyMatch(this::isConnectedInventory);
|
return Arrays.stream(Direction.values()).anyMatch(dir -> this.isConnectedInventory(dir, force));
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
IItemHandler handler = tile.getItemHandler(dir, false);
|
||||||
if (handler == null)
|
if (handler == null)
|
||||||
continue;
|
continue;
|
||||||
for (int j = 0; j < handler.getSlots(); j++) {
|
for (int j = 0; j < handler.getSlots(); j++) {
|
||||||
|
|
|
@ -58,9 +58,7 @@ public class RetrievalModuleItem extends ModuleItem {
|
||||||
for (NetworkLocation location : locations) {
|
for (NetworkLocation location : locations) {
|
||||||
if (location.pipePos.equals(tile.getPos()))
|
if (location.pipePos.equals(tile.getPos()))
|
||||||
continue;
|
continue;
|
||||||
int slot = location.getStackSlot(filtered);
|
for (int slot : location.getStackSlots(filtered)) {
|
||||||
if (slot < 0)
|
|
||||||
continue;
|
|
||||||
// try to extract from that location's inventory and send the item
|
// try to extract from that location's inventory and send the item
|
||||||
ItemStack stack = location.handler.extractItem(slot, this.maxExtraction, true);
|
ItemStack stack = location.handler.extractItem(slot, this.maxExtraction, true);
|
||||||
if (network.routeItemToLocation(location.pipePos, location.pos, tile.getPos(), dest, speed -> new PipeItem(stack, speed))) {
|
if (network.routeItemToLocation(location.pipePos, location.pos, tile.getPos(), dest, speed -> new PipeItem(stack, speed))) {
|
||||||
|
@ -70,6 +68,7 @@ public class RetrievalModuleItem extends ModuleItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canNetworkSee(ItemStack module, PipeTileEntity tile) {
|
public boolean canNetworkSee(ItemStack module, PipeTileEntity tile) {
|
||||||
|
|
|
@ -20,6 +20,7 @@ import net.minecraft.util.math.BlockRayTraceResult;
|
||||||
import net.minecraft.world.IBlockReader;
|
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 javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
@ -30,8 +31,6 @@ public class ItemTerminalBlock extends ContainerBlock implements IPipeConnectabl
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult result) {
|
public ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult result) {
|
||||||
if (!player.getHeldItem(handIn).isEmpty())
|
|
||||||
return ActionResultType.PASS;
|
|
||||||
ItemTerminalTileEntity tile = Utility.getTileEntity(ItemTerminalTileEntity.class, worldIn, pos);
|
ItemTerminalTileEntity tile = Utility.getTileEntity(ItemTerminalTileEntity.class, worldIn, pos);
|
||||||
if (tile == null)
|
if (tile == null)
|
||||||
return ActionResultType.PASS;
|
return ActionResultType.PASS;
|
||||||
|
@ -53,6 +52,16 @@ public class ItemTerminalBlock extends ContainerBlock implements IPipeConnectabl
|
||||||
return ConnectionType.CONNECTED;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockRenderType getRenderType(BlockState state) {
|
public BlockRenderType getRenderType(BlockState state) {
|
||||||
return BlockRenderType.MODEL;
|
return BlockRenderType.MODEL;
|
||||||
|
|
|
@ -6,6 +6,7 @@ import de.ellpeck.prettypipes.Utility;
|
||||||
import de.ellpeck.prettypipes.misc.EquatableItemStack;
|
import de.ellpeck.prettypipes.misc.EquatableItemStack;
|
||||||
import de.ellpeck.prettypipes.network.NetworkItem;
|
import de.ellpeck.prettypipes.network.NetworkItem;
|
||||||
import de.ellpeck.prettypipes.network.NetworkLocation;
|
import de.ellpeck.prettypipes.network.NetworkLocation;
|
||||||
|
import de.ellpeck.prettypipes.network.PipeItem;
|
||||||
import de.ellpeck.prettypipes.network.PipeNetwork;
|
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;
|
||||||
|
@ -24,10 +25,14 @@ import net.minecraft.tileentity.TileEntityType;
|
||||||
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.util.text.ITextComponent;
|
import net.minecraft.util.text.ITextComponent;
|
||||||
|
import net.minecraft.util.text.Style;
|
||||||
|
import net.minecraft.util.text.TextFormatting;
|
||||||
import net.minecraft.util.text.TranslationTextComponent;
|
import net.minecraft.util.text.TranslationTextComponent;
|
||||||
import net.minecraft.world.server.ServerWorld;
|
import net.minecraft.world.server.ServerWorld;
|
||||||
import net.minecraftforge.items.ItemStackHandler;
|
import net.minecraftforge.items.ItemStackHandler;
|
||||||
import org.apache.commons.lang3.mutable.MutableInt;
|
import org.apache.commons.lang3.mutable.MutableInt;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
import org.apache.commons.lang3.tuple.Triple;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
@ -39,10 +44,11 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
|
||||||
public final ItemStackHandler items = new ItemStackHandler(12) {
|
public final ItemStackHandler items = new ItemStackHandler(12) {
|
||||||
@Override
|
@Override
|
||||||
public boolean isItemValid(int slot, @Nonnull ItemStack stack) {
|
public boolean isItemValid(int slot, @Nonnull ItemStack stack) {
|
||||||
return slot >= 6;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
public Collection<NetworkItem> networkItems;
|
public Map<EquatableItemStack, NetworkItem> networkItems;
|
||||||
|
private Queue<Triple<NetworkLocation, Integer, Integer>> pendingRequests = new ArrayDeque<>();
|
||||||
|
|
||||||
public ItemTerminalTileEntity() {
|
public ItemTerminalTileEntity() {
|
||||||
super(Registry.itemTerminalTileEntity);
|
super(Registry.itemTerminalTileEntity);
|
||||||
|
@ -67,13 +73,20 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
|
||||||
this.items.extractItem(i, extracted.getCount(), false);
|
this.items.extractItem(i, extracted.getCount(), false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.world.getGameTime() % 100 == 0) {
|
if (this.world.getGameTime() % 100 == 0) {
|
||||||
PlayerEntity[] lookingPlayers = this.world.getPlayers().stream()
|
PlayerEntity[] lookingPlayers = this.getLookingPlayers();
|
||||||
.filter(p -> p.openContainer instanceof ItemTerminalContainer)
|
|
||||||
.filter(p -> ((ItemTerminalContainer) p.openContainer).tile == this)
|
|
||||||
.toArray(PlayerEntity[]::new);
|
|
||||||
if (lookingPlayers.length > 0)
|
if (lookingPlayers.length > 0)
|
||||||
this.updateItems(lookingPlayers);
|
this.updateItems(lookingPlayers);
|
||||||
}
|
}
|
||||||
|
@ -91,7 +104,8 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
|
||||||
|
|
||||||
public void updateItems(PlayerEntity... playersToSync) {
|
public void updateItems(PlayerEntity... playersToSync) {
|
||||||
this.networkItems = this.collectItems();
|
this.networkItems = this.collectItems();
|
||||||
List<ItemStack> clientItems = this.networkItems.stream().map(NetworkItem::asStack).collect(Collectors.toList());
|
if (playersToSync.length > 0) {
|
||||||
|
List<ItemStack> clientItems = this.networkItems.values().stream().map(NetworkItem::asStack).collect(Collectors.toList());
|
||||||
for (PlayerEntity player : playersToSync) {
|
for (PlayerEntity player : playersToSync) {
|
||||||
if (!(player.openContainer instanceof ItemTerminalContainer))
|
if (!(player.openContainer instanceof ItemTerminalContainer))
|
||||||
continue;
|
continue;
|
||||||
|
@ -101,8 +115,43 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
|
||||||
PacketHandler.sendTo(player, new PacketNetworkItems(clientItems));
|
PacketHandler.sendTo(player, new PacketNetworkItems(clientItems));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Collection<NetworkItem> collectItems() {
|
public void requestItem(PlayerEntity player, ItemStack stack) {
|
||||||
|
PipeNetwork network = PipeNetwork.get(this.world);
|
||||||
|
network.startProfile("terminal_request_item");
|
||||||
|
EquatableItemStack equatable = new EquatableItemStack(stack);
|
||||||
|
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)) {
|
||||||
|
ItemStack extracted = location.handler.extractItem(slot, remain, true);
|
||||||
|
if (!extracted.isEmpty()) {
|
||||||
|
this.pendingRequests.add(Triple.of(location, slot, extracted.getCount()));
|
||||||
|
remain -= extracted.getCount();
|
||||||
|
if (remain <= 0)
|
||||||
|
break locations;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
player.sendMessage(new TranslationTextComponent("info." + PrettyPipes.ID + ".sending", stack.getCount() - remain, stack.getDisplayName()).setStyle(new Style().setColor(TextFormatting.GREEN)));
|
||||||
|
this.updateItems(player);
|
||||||
|
} else {
|
||||||
|
player.sendMessage(new TranslationTextComponent("info." + PrettyPipes.ID + ".not_found", stack.getDisplayName()).setStyle(new Style().setColor(TextFormatting.RED)));
|
||||||
|
}
|
||||||
|
network.endProfile();
|
||||||
|
}
|
||||||
|
|
||||||
|
private PlayerEntity[] getLookingPlayers() {
|
||||||
|
return this.world.getPlayers().stream()
|
||||||
|
.filter(p -> p.openContainer instanceof ItemTerminalContainer)
|
||||||
|
.filter(p -> ((ItemTerminalContainer) p.openContainer).tile == this)
|
||||||
|
.toArray(PlayerEntity[]::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<EquatableItemStack, NetworkItem> collectItems() {
|
||||||
PipeNetwork network = PipeNetwork.get(this.world);
|
PipeNetwork network = PipeNetwork.get(this.world);
|
||||||
network.startProfile("terminal_collect_items");
|
network.startProfile("terminal_collect_items");
|
||||||
PipeTileEntity pipe = this.getConnectedPipe();
|
PipeTileEntity pipe = this.getConnectedPipe();
|
||||||
|
@ -115,7 +164,7 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
network.endProfile();
|
network.endProfile();
|
||||||
return items.values();
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -2,17 +2,29 @@ package de.ellpeck.prettypipes.terminal.containers;
|
||||||
|
|
||||||
import de.ellpeck.prettypipes.PrettyPipes;
|
import de.ellpeck.prettypipes.PrettyPipes;
|
||||||
import de.ellpeck.prettypipes.misc.ItemTerminalWidget;
|
import de.ellpeck.prettypipes.misc.ItemTerminalWidget;
|
||||||
|
import de.ellpeck.prettypipes.packets.PacketHandler;
|
||||||
|
import de.ellpeck.prettypipes.packets.PacketRequest;
|
||||||
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
|
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
|
||||||
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.item.ItemStack;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.text.ITextComponent;
|
import net.minecraft.util.text.ITextComponent;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class ItemTerminalGui extends ContainerScreen<ItemTerminalContainer> {
|
public class ItemTerminalGui extends ContainerScreen<ItemTerminalContainer> {
|
||||||
private static final ResourceLocation TEXTURE = new ResourceLocation(PrettyPipes.ID, "textures/gui/item_terminal.png");
|
private static final ResourceLocation TEXTURE = new ResourceLocation(PrettyPipes.ID, "textures/gui/item_terminal.png");
|
||||||
|
private List<ItemStack> items;
|
||||||
|
private Button minusButton;
|
||||||
|
private Button plusButton;
|
||||||
|
private Button requestButton;
|
||||||
|
private int requestAmount = 1;
|
||||||
|
|
||||||
public ItemTerminalGui(ItemTerminalContainer screenContainer, PlayerInventory inv, ITextComponent titleIn) {
|
public ItemTerminalGui(ItemTerminalContainer screenContainer, PlayerInventory inv, ITextComponent titleIn) {
|
||||||
super(screenContainer, inv, titleIn);
|
super(screenContainer, inv, titleIn);
|
||||||
|
@ -20,16 +32,65 @@ public class ItemTerminalGui extends ContainerScreen<ItemTerminalContainer> {
|
||||||
this.ySize = 236;
|
this.ySize = 236;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
super.init();
|
||||||
|
this.plusButton = this.addButton(new Button(this.guiLeft + this.xSize / 2 - 7 + 12, this.guiTop + 103, 12, 12, "+", button -> {
|
||||||
|
int modifier = requestModifier();
|
||||||
|
if (modifier > 1 && this.requestAmount == 1) {
|
||||||
|
this.requestAmount = modifier;
|
||||||
|
} else {
|
||||||
|
this.requestAmount += modifier;
|
||||||
|
}
|
||||||
|
if (this.requestAmount > 384)
|
||||||
|
this.requestAmount = 384;
|
||||||
|
}));
|
||||||
|
this.minusButton = this.addButton(new Button(this.guiLeft + this.xSize / 2 - 7 - 24, this.guiTop + 103, 12, 12, "-", button -> {
|
||||||
|
this.requestAmount -= requestModifier();
|
||||||
|
if (this.requestAmount < 1)
|
||||||
|
this.requestAmount = 1;
|
||||||
|
}));
|
||||||
|
this.minusButton.active = false;
|
||||||
|
this.requestButton = this.addButton(new Button(this.guiLeft + this.xSize / 2 - 7 - 25, this.guiTop + 115, 50, 20, I18n.format("info." + PrettyPipes.ID + ".request"), button -> {
|
||||||
|
Optional<ItemTerminalWidget> widget = this.streamWidgets().filter(w -> w.selected).findFirst();
|
||||||
|
if (!widget.isPresent())
|
||||||
|
return;
|
||||||
|
ItemStack stack = widget.get().stack.copy();
|
||||||
|
stack.setCount(1);
|
||||||
|
PacketHandler.sendToServer(new PacketRequest(this.container.tile.getPos(), stack, this.requestAmount));
|
||||||
|
this.requestAmount = 1;
|
||||||
|
}));
|
||||||
|
this.requestButton.active = false;
|
||||||
|
for (int y = 0; y < 4; y++) {
|
||||||
|
for (int x = 0; x < 9; x++)
|
||||||
|
this.addButton(new ItemTerminalWidget(this.guiLeft + 8 + x * 18, this.guiTop + 18 + y * 18, x, y, this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
super.tick();
|
||||||
|
this.requestButton.active = this.streamWidgets().anyMatch(w -> w.selected);
|
||||||
|
this.plusButton.active = this.requestAmount < 384;
|
||||||
|
this.minusButton.active = this.requestAmount > 1;
|
||||||
|
}
|
||||||
|
|
||||||
public void updateItemList(List<ItemStack> items) {
|
public void updateItemList(List<ItemStack> items) {
|
||||||
this.buttons.removeIf(w -> w instanceof ItemTerminalWidget);
|
this.items = items;
|
||||||
int x = 0;
|
this.updateWidgets(0);
|
||||||
int y = 0;
|
}
|
||||||
for (ItemStack stack : items) {
|
|
||||||
this.buttons.add(new ItemTerminalWidget(this.guiLeft + 8 + x * 18, this.guiTop + 18 + y * 18, x, y, stack, this));
|
private void updateWidgets(int scrollOffset) {
|
||||||
x++;
|
List<ItemTerminalWidget> widgets = this.streamWidgets().collect(Collectors.toList());
|
||||||
if (x > 8) {
|
for (int i = 0; i < widgets.size(); i++) {
|
||||||
x = 0;
|
ItemTerminalWidget widget = widgets.get(i);
|
||||||
y++;
|
int index = i + scrollOffset * 9;
|
||||||
|
if (index >= this.items.size()) {
|
||||||
|
widget.stack = ItemStack.EMPTY;
|
||||||
|
widget.visible = false;
|
||||||
|
} else {
|
||||||
|
widget.stack = this.items.get(index);
|
||||||
|
widget.visible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,6 +110,9 @@ public class ItemTerminalGui extends ContainerScreen<ItemTerminalContainer> {
|
||||||
protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
|
protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
|
||||||
this.font.drawString(this.playerInventory.getDisplayName().getFormattedText(), 8, this.ySize - 96 + 2, 4210752);
|
this.font.drawString(this.playerInventory.getDisplayName().getFormattedText(), 8, this.ySize - 96 + 2, 4210752);
|
||||||
this.font.drawString(this.title.getFormattedText(), 8, 6, 4210752);
|
this.font.drawString(this.title.getFormattedText(), 8, 6, 4210752);
|
||||||
|
|
||||||
|
String amount = String.valueOf(this.requestAmount);
|
||||||
|
this.font.drawString(amount, (this.xSize - this.font.getStringWidth(amount)) / 2F - 7, 106, 4210752);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -57,9 +121,19 @@ public class ItemTerminalGui extends ContainerScreen<ItemTerminalContainer> {
|
||||||
this.blit(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize);
|
this.blit(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// public overload for ItemTerminalWidget
|
public Stream<ItemTerminalWidget> streamWidgets() {
|
||||||
@Override
|
return this.buttons.stream()
|
||||||
public void renderTooltip(ItemStack stack, int x, int y) {
|
.filter(w -> w instanceof ItemTerminalWidget)
|
||||||
super.renderTooltip(stack, x, y);
|
.map(w -> (ItemTerminalWidget) w);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int requestModifier() {
|
||||||
|
if (hasControlDown()) {
|
||||||
|
return 10;
|
||||||
|
} else if (hasShiftDown()) {
|
||||||
|
return 64;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
"block.prettypipes.pipe": "Pipe",
|
"block.prettypipes.pipe": "Pipe",
|
||||||
"itemGroup.prettypipes": "Pretty Pipes",
|
"itemGroup.prettypipes": "Pretty Pipes",
|
||||||
"container.prettypipes.pipe": "Pipe",
|
"container.prettypipes.pipe": "Pipe",
|
||||||
|
"container.prettypipes.item_terminal": "Item Terminal",
|
||||||
"info.prettypipes.whitelist": "Allowed",
|
"info.prettypipes.whitelist": "Allowed",
|
||||||
"info.prettypipes.blacklist": "Disallowed",
|
"info.prettypipes.blacklist": "Disallowed",
|
||||||
"info.prettypipes.shift": "Hold Shift for info",
|
"info.prettypipes.shift": "Hold Shift for info",
|
||||||
|
@ -43,5 +44,8 @@
|
||||||
"info.prettypipes.populate.description": "Filters items from adjacent inventories",
|
"info.prettypipes.populate.description": "Filters items from adjacent inventories",
|
||||||
"info.prettypipes.max_stack_size": "Maximum item amount",
|
"info.prettypipes.max_stack_size": "Maximum item amount",
|
||||||
"info.prettypipes.limit_to_max_on": "Limit to one stack",
|
"info.prettypipes.limit_to_max_on": "Limit to one stack",
|
||||||
"info.prettypipes.limit_to_max_off": "Don't limit to one stack"
|
"info.prettypipes.limit_to_max_off": "Don't limit to one stack",
|
||||||
|
"info.prettypipes.request": "Request",
|
||||||
|
"info.prettypipes.not_found": "%s not found",
|
||||||
|
"info.prettypipes.sending": "Sending %s %s"
|
||||||
}
|
}
|
Loading…
Reference in a new issue