diff --git a/src/main/java/de/ellpeck/prettypipes/items/IModule.java b/src/main/java/de/ellpeck/prettypipes/items/IModule.java index 149fe16..a7cfe7d 100644 --- a/src/main/java/de/ellpeck/prettypipes/items/IModule.java +++ b/src/main/java/de/ellpeck/prettypipes/items/IModule.java @@ -7,6 +7,8 @@ import net.minecraft.entity.player.PlayerInventory; import net.minecraft.item.ItemStack; import net.minecraftforge.items.IItemHandler; +import java.util.List; + public interface IModule { void tick(ItemStack module, PipeTileEntity tile); @@ -28,4 +30,6 @@ public interface IModule { float getItemSpeedIncrease(ItemStack module, PipeTileEntity tile); boolean canPipeWork(ItemStack module, PipeTileEntity tile); + + List getCraftables(ItemStack module, PipeTileEntity tile); } diff --git a/src/main/java/de/ellpeck/prettypipes/items/ModuleItem.java b/src/main/java/de/ellpeck/prettypipes/items/ModuleItem.java index f28f5b2..8fc99ce 100644 --- a/src/main/java/de/ellpeck/prettypipes/items/ModuleItem.java +++ b/src/main/java/de/ellpeck/prettypipes/items/ModuleItem.java @@ -16,6 +16,7 @@ import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.items.IItemHandler; import javax.annotation.Nullable; +import java.util.Collections; import java.util.List; public abstract class ModuleItem extends Item implements IModule { @@ -73,4 +74,9 @@ public abstract class ModuleItem extends Item implements IModule { public boolean canPipeWork(ItemStack module, PipeTileEntity tile) { return true; } + + @Override + public List getCraftables(ItemStack module, PipeTileEntity tile) { + return Collections.emptyList(); + } } diff --git a/src/main/java/de/ellpeck/prettypipes/misc/ItemTerminalWidget.java b/src/main/java/de/ellpeck/prettypipes/misc/ItemTerminalWidget.java index 5b3bded..714cac6 100644 --- a/src/main/java/de/ellpeck/prettypipes/misc/ItemTerminalWidget.java +++ b/src/main/java/de/ellpeck/prettypipes/misc/ItemTerminalWidget.java @@ -16,6 +16,7 @@ import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.TextComponent; import net.minecraft.util.text.TextFormatting; import net.minecraftforge.fml.client.gui.GuiUtils; +import org.apache.commons.lang3.tuple.Pair; import java.util.List; @@ -27,6 +28,7 @@ public class ItemTerminalWidget extends Widget { public final int gridY; public boolean selected; public ItemStack stack = ItemStack.EMPTY; + public boolean craftable; public ItemTerminalWidget(int xIn, int yIn, int gridX, int gridY, ItemTerminalGui screen) { super(xIn, yIn, 16, 16, new StringTextComponent("")); @@ -52,7 +54,7 @@ public class ItemTerminalWidget extends Widget { fill(matrix, this.x, this.y, this.x + 16, this.y + 16, -2130706433); RenderSystem.enableDepthTest(); renderer.renderItemAndEffectIntoGUI(mc.player, this.stack, this.x, this.y); - int amount = this.stack.getCount(); + int amount = !this.craftable ? this.stack.getCount() : 0; String amountStrg = this.stack.getCount() >= 1000 ? amount / 1000 + "k" : String.valueOf(amount); RenderSystem.pushMatrix(); RenderSystem.scalef(0.8F, 0.8F, 1); diff --git a/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java b/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java index 4b4fb2e..01a302a 100644 --- a/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java +++ b/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java @@ -224,6 +224,24 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL return tile; } + public List> getOrderedCraftables(BlockPos node) { + if (!this.isNode(node)) + return Collections.emptyList(); + this.startProfile("get_craftables"); + List> craftables = new ArrayList<>(); + for (BlockPos dest : this.getOrderedNetworkNodes(node)) { + if (!this.world.isBlockLoaded(dest)) + continue; + PipeTileEntity pipe = this.getPipe(dest); + if (!pipe.canNetworkSee()) + continue; + for (ItemStack stack : pipe.getCraftables()) + craftables.add(Pair.of(pipe.getPos(), stack)); + } + this.endProfile(); + return craftables; + } + public List getOrderedNetworkItems(BlockPos node) { if (!this.isNode(node)) return Collections.emptyList(); diff --git a/src/main/java/de/ellpeck/prettypipes/packets/PacketNetworkItems.java b/src/main/java/de/ellpeck/prettypipes/packets/PacketNetworkItems.java index ef65b03..944541e 100644 --- a/src/main/java/de/ellpeck/prettypipes/packets/PacketNetworkItems.java +++ b/src/main/java/de/ellpeck/prettypipes/packets/PacketNetworkItems.java @@ -22,9 +22,11 @@ import java.util.function.Supplier; public class PacketNetworkItems { private List items; + private List craftables; - public PacketNetworkItems(List items) { + public PacketNetworkItems(List items, List craftables) { this.items = items; + this.craftables = craftables; } private PacketNetworkItems() { @@ -39,6 +41,9 @@ public class PacketNetworkItems { stack.setCount(buf.readVarInt()); client.items.add(stack); } + client.craftables = new ArrayList<>(); + for (int i = buf.readVarInt(); i > 0; i--) + client.craftables.add(buf.readItemStack()); return client; } @@ -50,6 +55,9 @@ public class PacketNetworkItems { buf.writeItemStack(copy); buf.writeVarInt(stack.getCount()); } + buf.writeVarInt(packet.craftables.size()); + for (ItemStack stack : packet.craftables) + buf.writeItemStack(stack); } @SuppressWarnings("Convert2Lambda") @@ -59,7 +67,7 @@ public class PacketNetworkItems { public void run() { Minecraft mc = Minecraft.getInstance(); if (mc.currentScreen instanceof ItemTerminalGui) - ((ItemTerminalGui) mc.currentScreen).updateItemList(message.items); + ((ItemTerminalGui) mc.currentScreen).updateItemList(message.items, message.craftables); } }); ctx.get().setPacketHandled(true); diff --git a/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java b/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java index 830c1cb..b668fb4 100644 --- a/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java +++ b/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java @@ -37,6 +37,7 @@ import org.apache.commons.lang3.tuple.Pair; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.*; +import java.util.stream.Collectors; import java.util.stream.Stream; public class PipeTileEntity extends TileEntity implements INamedContainerProvider, ITickableTileEntity { @@ -231,6 +232,12 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide return this.streamModules().allMatch(m -> m.getRight().canPipeWork(m.getLeft(), this)); } + public List getCraftables() { + return this.streamModules() + .flatMap(m -> m.getRight().getCraftables(m.getLeft(), this).stream()) + .collect(Collectors.toList()); + } + public IItemHandler getItemHandler(Direction dir, PipeItem item) { if (!this.isConnected(dir)) return null; diff --git a/src/main/java/de/ellpeck/prettypipes/pipe/modules/craft/CraftingModuleItem.java b/src/main/java/de/ellpeck/prettypipes/pipe/modules/craft/CraftingModuleItem.java index aa79f34..263843b 100644 --- a/src/main/java/de/ellpeck/prettypipes/pipe/modules/craft/CraftingModuleItem.java +++ b/src/main/java/de/ellpeck/prettypipes/pipe/modules/craft/CraftingModuleItem.java @@ -12,6 +12,9 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; import net.minecraftforge.items.ItemStackHandler; +import java.util.ArrayList; +import java.util.List; + public class CraftingModuleItem extends ModuleItem { public final int inputSlots; @@ -38,6 +41,18 @@ public class CraftingModuleItem extends ModuleItem { return new CraftingModuleContainer(Registry.craftingModuleContainer, windowId, player, tile.getPos(), moduleIndex); } + @Override + public List getCraftables(ItemStack module, PipeTileEntity tile) { + ItemStackHandler output = this.getOutput(module); + List items = new ArrayList<>(); + for (int i = 0; i < output.getSlots(); i++) { + ItemStack stack = output.getStackInSlot(i); + if (!stack.isEmpty()) + items.add(stack); + } + return items; + } + public ItemStackHandler getInput(ItemStack module) { ItemStackHandler handler = new ItemStackHandler(this.inputSlots); if (module.hasTag()) diff --git a/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalTileEntity.java b/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalTileEntity.java index daa63dd..defa9cf 100644 --- a/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalTileEntity.java +++ b/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalTileEntity.java @@ -51,6 +51,7 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine } }; public Map networkItems; + public List> craftables; private final Queue pendingRequests = new ArrayDeque<>(); protected ItemTerminalTileEntity(TileEntityType tileEntityTypeIn) { @@ -118,18 +119,21 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine } public void updateItems(PlayerEntity... playersToSync) { - if (this.getConnectedPipe() == null) + PipeTileEntity pipe = this.getConnectedPipe(); + if (pipe == null) return; this.networkItems = this.collectItems(); + this.craftables = PipeNetwork.get(this.world).getOrderedCraftables(pipe.getPos()); if (playersToSync.length > 0) { List clientItems = this.networkItems.values().stream().map(NetworkItem::asStack).collect(Collectors.toList()); + List clientCraftables = this.craftables.stream().map(Pair::getRight).collect(Collectors.toList()); for (PlayerEntity player : playersToSync) { if (!(player.openContainer instanceof ItemTerminalContainer)) continue; ItemTerminalTileEntity tile = ((ItemTerminalContainer) player.openContainer).tile; if (tile != this) continue; - PacketHandler.sendTo(player, new PacketNetworkItems(clientItems)); + PacketHandler.sendTo(player, new PacketNetworkItems(clientItems, clientCraftables)); } } } diff --git a/src/main/java/de/ellpeck/prettypipes/terminal/containers/ItemTerminalGui.java b/src/main/java/de/ellpeck/prettypipes/terminal/containers/ItemTerminalGui.java index 5644503..d59e998 100644 --- a/src/main/java/de/ellpeck/prettypipes/terminal/containers/ItemTerminalGui.java +++ b/src/main/java/de/ellpeck/prettypipes/terminal/containers/ItemTerminalGui.java @@ -22,15 +22,20 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.TranslationTextComponent; +import org.apache.commons.lang3.tuple.Pair; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; public class ItemTerminalGui extends ContainerScreen { + private static final ResourceLocation TEXTURE = new ResourceLocation(PrettyPipes.ID, "textures/gui/item_terminal.png"); + + // craftables have the second parameter set to true + private final List> sortedItems = new ArrayList<>(); private List items; - private List sortedItems; + private List craftables; private Button minusButton; private Button plusButton; private Button requestButton; @@ -136,8 +141,9 @@ public class ItemTerminalGui extends ContainerScreen { return super.keyPressed(x, y, z); } - public void updateItemList(List items) { + public void updateItemList(List items, List craftables) { this.items = items; + this.craftables = craftables; this.updateWidgets(); } @@ -150,8 +156,16 @@ public class ItemTerminalGui extends ContainerScreen { if (!prefs.terminalAscending) comparator = comparator.reversed(); - this.sortedItems = new ArrayList<>(this.items); - this.sortedItems.sort(comparator); + // add all items to the sorted items list + this.sortedItems.clear(); + for (ItemStack stack : this.items) + this.sortedItems.add(Pair.of(stack, false)); + for (ItemStack stack : this.craftables) + this.sortedItems.add(Pair.of(stack, true)); + + // compare by craftability first, and then by the player's chosen order + Comparator> fullComparator = Comparator.comparing(Pair::getRight); + this.sortedItems.sort(fullComparator.thenComparing(Pair::getLeft, comparator)); String searchText = this.search.getText(); if (!Strings.isNullOrEmpty(searchText)) { @@ -159,11 +173,11 @@ public class ItemTerminalGui extends ContainerScreen { String search = searchText; String toCompare; if (search.startsWith("@")) { - toCompare = s.getItem().getRegistryName().getNamespace(); + toCompare = s.getLeft().getItem().getRegistryName().getNamespace(); search = search.substring(1); } else { // don't use formatted text here since we want to search for name - toCompare = s.getDisplayName().getString(); + toCompare = s.getLeft().getDisplayName().getString(); } return !toCompare.toLowerCase(Locale.ROOT).contains(search.toLowerCase(Locale.ROOT)); }); @@ -178,9 +192,12 @@ public class ItemTerminalGui extends ContainerScreen { int index = i + this.scrollOffset * 9; if (index >= this.sortedItems.size()) { widget.stack = ItemStack.EMPTY; + widget.craftable = false; widget.visible = false; } else { - widget.stack = this.sortedItems.get(index); + Pair stack = this.sortedItems.get(index); + widget.stack = stack.getLeft(); + widget.craftable = stack.getRight(); widget.visible = true; } }