diff --git a/src/main/java/de/ellpeck/prettypipes/misc/ItemOrder.java b/src/main/java/de/ellpeck/prettypipes/misc/ItemOrder.java new file mode 100644 index 0000000..628e85b --- /dev/null +++ b/src/main/java/de/ellpeck/prettypipes/misc/ItemOrder.java @@ -0,0 +1,17 @@ +package de.ellpeck.prettypipes.misc; + +import net.minecraft.item.ItemStack; + +import java.util.Comparator; + +public enum ItemOrder { + AMOUNT(Comparator.comparingInt(ItemStack::getCount)), + NAME(Comparator.comparing(s -> s.getDisplayName().getFormattedText())), + MOD(Comparator.comparing(s -> s.getItem().getRegistryName().getNamespace())); + + public final Comparator comparator; + + ItemOrder(Comparator comparator) { + this.comparator = comparator; + } +} diff --git a/src/main/java/de/ellpeck/prettypipes/misc/ItemTerminalWidget.java b/src/main/java/de/ellpeck/prettypipes/misc/ItemTerminalWidget.java index d323b7d..cfff96e 100644 --- a/src/main/java/de/ellpeck/prettypipes/misc/ItemTerminalWidget.java +++ b/src/main/java/de/ellpeck/prettypipes/misc/ItemTerminalWidget.java @@ -29,6 +29,7 @@ public class ItemTerminalWidget extends Widget { this.gridX = gridX; this.gridY = gridY; this.screen = screen; + this.visible = false; } @Override diff --git a/src/main/java/de/ellpeck/prettypipes/packets/PacketButton.java b/src/main/java/de/ellpeck/prettypipes/packets/PacketButton.java index eb707d8..ce0efd9 100644 --- a/src/main/java/de/ellpeck/prettypipes/packets/PacketButton.java +++ b/src/main/java/de/ellpeck/prettypipes/packets/PacketButton.java @@ -1,5 +1,6 @@ package de.ellpeck.prettypipes.packets; +import de.ellpeck.prettypipes.PrettyPipes; import de.ellpeck.prettypipes.Utility; import de.ellpeck.prettypipes.items.IModule; import de.ellpeck.prettypipes.misc.ItemFilter; @@ -7,6 +8,7 @@ import de.ellpeck.prettypipes.misc.ItemFilter.IFilteredContainer; import de.ellpeck.prettypipes.pipe.PipeTileEntity; import de.ellpeck.prettypipes.pipe.containers.AbstractPipeContainer; import de.ellpeck.prettypipes.pipe.modules.stacksize.StackSizeModuleItem; +import de.ellpeck.prettypipes.terminal.ItemTerminalTileEntity; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; @@ -107,6 +109,14 @@ public class PacketButton { STACK_SIZE_AMOUNT((pos, data, player) -> { AbstractPipeContainer container = (AbstractPipeContainer) player.openContainer; StackSizeModuleItem.setMaxStackSize(container.moduleStack, data[0]); + }), + TERMINAL_ORDER((pos, data, player) -> { + player.getPersistentData().putInt(PrettyPipes.ID + ":item_order", data[0]); + Utility.getTileEntity(ItemTerminalTileEntity.class, player.world, pos).updateItems(player); + }), + TERMINAL_ASCENDING((pos, data, player) -> { + player.getPersistentData().putBoolean(PrettyPipes.ID + ":ascending", data[0] > 0); + Utility.getTileEntity(ItemTerminalTileEntity.class, player.world, pos).updateItems(player); }); public final TriConsumer action; diff --git a/src/main/java/de/ellpeck/prettypipes/packets/PacketNetworkItems.java b/src/main/java/de/ellpeck/prettypipes/packets/PacketNetworkItems.java index db2be74..be0aa52 100644 --- a/src/main/java/de/ellpeck/prettypipes/packets/PacketNetworkItems.java +++ b/src/main/java/de/ellpeck/prettypipes/packets/PacketNetworkItems.java @@ -1,6 +1,7 @@ package de.ellpeck.prettypipes.packets; import de.ellpeck.prettypipes.Utility; +import de.ellpeck.prettypipes.misc.ItemOrder; import de.ellpeck.prettypipes.network.PipeItem; import de.ellpeck.prettypipes.pipe.PipeTileEntity; import de.ellpeck.prettypipes.terminal.containers.ItemTerminalContainer; @@ -21,9 +22,13 @@ import java.util.function.Supplier; public class PacketNetworkItems { private List items; + private ItemOrder order; + private boolean ascending; - public PacketNetworkItems(List items) { + public PacketNetworkItems(List items, ItemOrder order, boolean ascending) { this.items = items; + this.order = order; + this.ascending = ascending; } private PacketNetworkItems() { @@ -38,6 +43,8 @@ public class PacketNetworkItems { stack.setCount(buf.readVarInt()); client.items.add(stack); } + client.order = ItemOrder.values()[buf.readByte()]; + client.ascending = buf.readBoolean(); return client; } @@ -49,6 +56,8 @@ public class PacketNetworkItems { buf.writeItemStack(copy); buf.writeVarInt(stack.getCount()); } + buf.writeByte(packet.order.ordinal()); + buf.writeBoolean(packet.ascending); } @SuppressWarnings("Convert2Lambda") @@ -58,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.order, message.ascending); } }); ctx.get().setPacketHandled(true); diff --git a/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalBlock.java b/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalBlock.java index 416c3cf..c3f543d 100644 --- a/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalBlock.java +++ b/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalBlock.java @@ -1,6 +1,7 @@ package de.ellpeck.prettypipes.terminal; import de.ellpeck.prettypipes.Utility; +import de.ellpeck.prettypipes.network.PipeItem; import de.ellpeck.prettypipes.pipe.ConnectionType; import de.ellpeck.prettypipes.pipe.IPipeConnectable; import de.ellpeck.prettypipes.pipe.PipeTileEntity; @@ -9,20 +10,24 @@ import net.minecraft.block.BlockState; import net.minecraft.block.ContainerBlock; import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; +import net.minecraft.client.util.ITooltipFlag; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ActionResultType; import net.minecraft.util.Direction; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.text.ITextComponent; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; import net.minecraftforge.fml.network.NetworkHooks; import net.minecraftforge.items.IItemHandler; import javax.annotation.Nullable; +import java.util.List; public class ItemTerminalBlock extends ContainerBlock implements IPipeConnectable { public ItemTerminalBlock() { @@ -32,7 +37,7 @@ public class ItemTerminalBlock extends ContainerBlock implements IPipeConnectabl @Override public ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult result) { ItemTerminalTileEntity tile = Utility.getTileEntity(ItemTerminalTileEntity.class, worldIn, pos); - if (tile == null) + if (tile == null || tile.getConnectedPipe() == null) return ActionResultType.PASS; if (!worldIn.isRemote) { NetworkHooks.openGui((ServerPlayerEntity) player, tile, pos); @@ -41,6 +46,16 @@ public class ItemTerminalBlock extends ContainerBlock implements IPipeConnectabl return ActionResultType.SUCCESS; } + @Override + public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) { + if (state.getBlock() != newState.getBlock()) { + ItemTerminalTileEntity tile = Utility.getTileEntity(ItemTerminalTileEntity.class, worldIn, pos); + if (tile != null) + Utility.dropInventory(tile, tile.items); + super.onReplaced(state, worldIn, pos, newState, isMoving); + } + } + @Nullable @Override public TileEntity createNewTileEntity(IBlockReader worldIn) { @@ -66,4 +81,9 @@ public class ItemTerminalBlock extends ContainerBlock implements IPipeConnectabl public BlockRenderType getRenderType(BlockState state) { return BlockRenderType.MODEL; } + + @Override + public void addInformation(ItemStack stack, @Nullable IBlockReader worldIn, List tooltip, ITooltipFlag flagIn) { + Utility.addTooltip(this.getRegistryName().getPath(), tooltip); + } } diff --git a/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalTileEntity.java b/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalTileEntity.java index 99c85bd..48f0a50 100644 --- a/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalTileEntity.java +++ b/src/main/java/de/ellpeck/prettypipes/terminal/ItemTerminalTileEntity.java @@ -4,6 +4,7 @@ import de.ellpeck.prettypipes.PrettyPipes; import de.ellpeck.prettypipes.Registry; import de.ellpeck.prettypipes.Utility; import de.ellpeck.prettypipes.misc.EquatableItemStack; +import de.ellpeck.prettypipes.misc.ItemOrder; import de.ellpeck.prettypipes.network.NetworkItem; import de.ellpeck.prettypipes.network.NetworkLocation; import de.ellpeck.prettypipes.network.PipeItem; @@ -48,7 +49,7 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine } }; public Map networkItems; - private Queue> pendingRequests = new ArrayDeque<>(); + private final Queue> pendingRequests = new ArrayDeque<>(); public ItemTerminalTileEntity() { super(Registry.itemTerminalTileEntity); @@ -95,7 +96,7 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine } } - private PipeTileEntity getConnectedPipe() { + public PipeTileEntity getConnectedPipe() { PipeNetwork network = PipeNetwork.get(this.world); for (Direction dir : Direction.values()) { PipeTileEntity pipe = network.getPipe(this.pos.offset(dir)); @@ -106,6 +107,8 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine } public void updateItems(PlayerEntity... playersToSync) { + if (this.getConnectedPipe() == null) + return; this.networkItems = this.collectItems(); if (playersToSync.length > 0) { List clientItems = this.networkItems.values().stream().map(NetworkItem::asStack).collect(Collectors.toList()); @@ -115,7 +118,11 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine ItemTerminalTileEntity tile = ((ItemTerminalContainer) player.openContainer).tile; if (tile != this) continue; - PacketHandler.sendTo(player, new PacketNetworkItems(clientItems)); + + CompoundNBT nbt = player.getPersistentData(); + ItemOrder order = ItemOrder.values()[nbt.getInt(PrettyPipes.ID + ":item_order")]; + boolean ascending = nbt.getBoolean(PrettyPipes.ID + ":ascending"); + PacketHandler.sendTo(player, new PacketNetworkItems(clientItems, order, ascending)); } } } 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 e24a00d..02ef475 100644 --- a/src/main/java/de/ellpeck/prettypipes/terminal/containers/ItemTerminalGui.java +++ b/src/main/java/de/ellpeck/prettypipes/terminal/containers/ItemTerminalGui.java @@ -1,7 +1,9 @@ package de.ellpeck.prettypipes.terminal.containers; import de.ellpeck.prettypipes.PrettyPipes; +import de.ellpeck.prettypipes.misc.ItemOrder; import de.ellpeck.prettypipes.misc.ItemTerminalWidget; +import de.ellpeck.prettypipes.packets.PacketButton; import de.ellpeck.prettypipes.packets.PacketHandler; import de.ellpeck.prettypipes.packets.PacketRequest; import net.minecraft.client.gui.screen.inventory.ContainerScreen; @@ -14,8 +16,7 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.MathHelper; import net.minecraft.util.text.ITextComponent; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -25,8 +26,12 @@ public class ItemTerminalGui extends ContainerScreen { private Button minusButton; private Button plusButton; private Button requestButton; + private Button orderButton; + private Button ascendingButton; private int requestAmount = 1; private int scrollOffset; + private ItemOrder order; + private boolean ascending; public ItemTerminalGui(ItemTerminalContainer screenContainer, PlayerInventory inv, ITextComponent titleIn) { super(screenContainer, inv, titleIn); @@ -63,6 +68,18 @@ public class ItemTerminalGui extends ContainerScreen { this.requestAmount = 1; })); this.requestButton.active = false; + this.orderButton = this.addButton(new Button(this.guiLeft - 22, this.guiTop, 20, 20, "", button -> { + if (this.items == null) + return; + int order = (this.order.ordinal() + 1) % ItemOrder.values().length; + PacketHandler.sendToServer(new PacketButton(this.container.tile.getPos(), PacketButton.ButtonResult.TERMINAL_ORDER, order)); + })); + this.ascendingButton = this.addButton(new Button(this.guiLeft - 22, this.guiTop + 22, 20, 20, "", button -> { + if (this.items == null) + return; + int asc = !this.ascending ? 1 : 0; + PacketHandler.sendToServer(new PacketButton(this.container.tile.getPos(), PacketButton.ButtonResult.TERMINAL_ASCENDING, asc)); + })); 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)); @@ -77,12 +94,22 @@ public class ItemTerminalGui extends ContainerScreen { this.minusButton.active = this.requestAmount > 1; } - public void updateItemList(List items) { - this.items = items; + public void updateItemList(List items, ItemOrder order, boolean ascending) { + this.order = order; + this.ascending = ascending; + this.items = new ArrayList<>(items); this.updateWidgets(); + + this.ascendingButton.setMessage(this.ascending ? "^" : "v"); + this.orderButton.setMessage(this.order.name().substring(0, 1)); } private void updateWidgets() { + Comparator comparator = this.order.comparator; + if (!this.ascending) + comparator = comparator.reversed(); + this.items.sort(comparator); + List widgets = this.streamWidgets().collect(Collectors.toList()); for (int i = 0; i < widgets.size(); i++) { ItemTerminalWidget widget = widgets.get(i); @@ -105,6 +132,12 @@ public class ItemTerminalGui extends ContainerScreen { if (widget instanceof ItemTerminalWidget) widget.renderToolTip(mouseX, mouseY); } + if (this.items != null) { + if (this.orderButton.isHovered()) + this.renderTooltip(I18n.format("info." + PrettyPipes.ID + ".order", I18n.format("info." + PrettyPipes.ID + ".order." + this.order.name().toLowerCase(Locale.ROOT))), mouseX, mouseY); + if (this.ascendingButton.isHovered()) + this.renderTooltip(I18n.format("info." + PrettyPipes.ID + "." + (this.ascending ? "ascending" : "descending")), mouseX, mouseY); + } this.renderHoveredToolTip(mouseX, mouseY); } diff --git a/src/main/resources/assets/prettypipes/blockstates/item_terminal.json b/src/main/resources/assets/prettypipes/blockstates/item_terminal.json new file mode 100644 index 0000000..f81d838 --- /dev/null +++ b/src/main/resources/assets/prettypipes/blockstates/item_terminal.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "prettypipes:block/item_terminal" + } + } +} diff --git a/src/main/resources/assets/prettypipes/lang/en_us.json b/src/main/resources/assets/prettypipes/lang/en_us.json index f0929bb..48af1ab 100644 --- a/src/main/resources/assets/prettypipes/lang/en_us.json +++ b/src/main/resources/assets/prettypipes/lang/en_us.json @@ -33,7 +33,9 @@ "info.prettypipes.nbt_filter_modifier": "Causes any filter slots to filter by item data (NBT)", "info.prettypipes.tag_filter_modifier": "Causes any filter slots to filter by tags\n(Modern equivalent of the Ore Dictionary)", "info.prettypipes.redstone_module": "Allows disabling the pipe with a redstone signal\nWorks for both extraction and retrieval", + "info.prettypipes.item_terminal": "Allows viewing and requesting all items in a pipe network\nAlso has slots for putting items into the network", "block.prettypipes.pipe": "Pipe", + "block.prettypipes.item_terminal": "Item Terminal", "itemGroup.prettypipes": "Pretty Pipes", "container.prettypipes.pipe": "Pipe", "container.prettypipes.item_terminal": "Item Terminal", @@ -47,5 +49,11 @@ "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" + "info.prettypipes.sending": "Sending %s %s", + "info.prettypipes.order": "Order by %s", + "info.prettypipes.order.amount": "Amount", + "info.prettypipes.order.name": "Name", + "info.prettypipes.order.mod": "Mod", + "info.prettypipes.ascending": "Ascending", + "info.prettypipes.descending": "Descending" } \ No newline at end of file diff --git a/src/main/resources/assets/prettypipes/models/block/item_terminal.json b/src/main/resources/assets/prettypipes/models/block/item_terminal.json new file mode 100644 index 0000000..7b46084 --- /dev/null +++ b/src/main/resources/assets/prettypipes/models/block/item_terminal.json @@ -0,0 +1,7 @@ +{ + "parent": "block/cube_column", + "textures": { + "end": "prettypipes:block/item_terminal_top", + "side": "prettypipes:block/item_terminal" + } +} diff --git a/src/main/resources/assets/prettypipes/models/item/item_terminal.json b/src/main/resources/assets/prettypipes/models/item/item_terminal.json new file mode 100644 index 0000000..36203be --- /dev/null +++ b/src/main/resources/assets/prettypipes/models/item/item_terminal.json @@ -0,0 +1,3 @@ +{ + "parent": "prettypipes:block/item_terminal" +} \ No newline at end of file diff --git a/src/main/resources/assets/prettypipes/textures/block/item_terminal.png b/src/main/resources/assets/prettypipes/textures/block/item_terminal.png new file mode 100644 index 0000000..0079a70 Binary files /dev/null and b/src/main/resources/assets/prettypipes/textures/block/item_terminal.png differ diff --git a/src/main/resources/assets/prettypipes/textures/block/item_terminal_top.png b/src/main/resources/assets/prettypipes/textures/block/item_terminal_top.png new file mode 100644 index 0000000..11b8c8b Binary files /dev/null and b/src/main/resources/assets/prettypipes/textures/block/item_terminal_top.png differ diff --git a/src/main/resources/data/prettypipes/recipes/item_terminal.json b/src/main/resources/data/prettypipes/recipes/item_terminal.json new file mode 100644 index 0000000..43b28b8 --- /dev/null +++ b/src/main/resources/data/prettypipes/recipes/item_terminal.json @@ -0,0 +1,31 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "DPI", + "RCE", + "IPD" + ], + "key": { + "E": { + "item": "prettypipes:high_extraction_module" + }, + "R": { + "item": "prettypipes:high_retrieval_module" + }, + "P": { + "item": "minecraft:ender_pearl" + }, + "I": { + "item": "minecraft:iron_block" + }, + "C": { + "item": "minecraft:chest" + }, + "D": { + "item": "minecraft:diamond_block" + } + }, + "result": { + "item": "prettypipes:item_terminal" + } +} \ No newline at end of file