diff --git a/gradle.properties b/gradle.properties index f00b731..b8a99ae 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ java_toolchain_version=21 mod_loader=neoforge minecraft_version=1.21.1 -neoforge_version=21.1.23 +neoforge_version=21.1.83 neoforge_dependency=[21.0.8-beta,) corelib_version=2.1.4 diff --git a/src/main/java/de/maxhenkel/pipez/Filter.java b/src/main/java/de/maxhenkel/pipez/Filter.java index 058ba94..ff19c78 100644 --- a/src/main/java/de/maxhenkel/pipez/Filter.java +++ b/src/main/java/de/maxhenkel/pipez/Filter.java @@ -2,15 +2,30 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; +import de.maxhenkel.corelib.helpers.AbstractStack; +import de.maxhenkel.corelib.helpers.WrappedFluidStack; +import de.maxhenkel.corelib.helpers.WrappedItemStack; import de.maxhenkel.corelib.tag.SingleElementTag; import de.maxhenkel.corelib.tag.Tag; +import de.maxhenkel.pipez.utils.ComponentUtils; +import de.maxhenkel.pipez.utils.MekanismUtils; import de.maxhenkel.pipez.utils.NbtUtils; +import de.maxhenkel.pipez.utils.WrappedGasStack; +import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.core.BlockPos; import net.minecraft.core.UUIDUtil; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.material.Fluid; +import net.neoforged.neoforge.fluids.FluidStack; import javax.annotation.Nullable; import java.lang.reflect.Constructor; @@ -247,4 +262,69 @@ public boolean isSingle() { } } + public static T get(Tag tag) { + long time = Minecraft.getInstance().level.getGameTime(); + List allElements = tag.getAll().stream().toList(); + return allElements.get((int) (time / 20L % allElements.size())); + } + + @Nullable + public AbstractStack getStack() { + Object o = null; + + if (this.getTag() != null) { + o = get(this.getTag()); + } + + if (o instanceof Item) { + ItemStack stack = new ItemStack((Item) o); + if (this.getMetadata() != null) { + stack.applyComponents(ComponentUtils.getPatch(Minecraft.getInstance().level.registryAccess(), this.getMetadata().copy())); + } + return new WrappedItemStack(stack); + } else if (o instanceof Fluid) { + FluidStack stack = new FluidStack((Fluid) o, 1000); + if (this.getMetadata() != null) { + stack.applyComponents(ComponentUtils.getPatch(Minecraft.getInstance().level.registryAccess(), this.getMetadata().copy())); + } + return new WrappedFluidStack(stack); + } + + if (MekanismUtils.isMekanismInstalled()) { + AbstractStack gasStack = WrappedGasStack.dummyStack(o); + if (gasStack != null) { + return gasStack; + } + } + + return null; + } + + public MutableComponent getTranslatedName() { + AbstractStack stack = this.getStack(); + if (stack != null && !stack.isEmpty() && this.getTag() != null) { + if (this.getTag() instanceof SingleElementTag) { + return Component.translatable(stack.getDisplayName().getString()); + } else { + return Component.literal(this.getTag().getName().toString()); + } + } + return Component.translatable("message.pipez.filter.any_item").withStyle(ChatFormatting.WHITE); + } + + public boolean hasDestination() { + return this.destination != null; + } + + @Nullable + public Integer getDistanceTo(BlockPos pos) { + DirectionalPosition destination = this.getDestination(); + if (destination == null) { + return null; + } + + BlockPos posFilter = destination.getPos(); + + return posFilter.distManhattan(pos); + } } diff --git a/src/main/java/de/maxhenkel/pipez/gui/CycleIconButton.java b/src/main/java/de/maxhenkel/pipez/gui/CycleIconButton.java index e927265..32a9bb8 100644 --- a/src/main/java/de/maxhenkel/pipez/gui/CycleIconButton.java +++ b/src/main/java/de/maxhenkel/pipez/gui/CycleIconButton.java @@ -6,7 +6,6 @@ import net.minecraft.client.gui.narration.NarrationElementOutput; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; import java.util.List; import java.util.function.Consumer; @@ -14,11 +13,12 @@ public class CycleIconButton extends AbstractButton { - private List icons; + private List icons; private Supplier index; private Consumer onPress; - public CycleIconButton(int x, int y, List icons, Supplier index, Consumer onPress) { + public CycleIconButton(int x, int y, List icons, Supplier index, Consumer onPress) { + // TODO ---> 20 super(x, y, 20, 20, Component.empty()); this.icons = icons; this.index = index; @@ -28,10 +28,10 @@ public CycleIconButton(int x, int y, List icons, Supplier index, @Override public void renderWidget(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTicks) { super.renderWidget(guiGraphics, mouseX, mouseY, partialTicks); - Icon icon = icons.get(index.get()); + IconButton.Icon icon = icons.get(index.get()); RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.setShaderColor(1F, 1F, 1F, 1F); - guiGraphics.blit(icon.texture, getX() + 2, getY() + 2, icon.offsetX, icon.offsetY, 16, 16); + guiGraphics.blit(icon.texture, getX() + 2, getY() + 2, icon.spriteRect.x, icon.spriteRect.y, icon.spriteRect.w, icon.spriteRect.h); } @Override @@ -43,16 +43,4 @@ protected void updateWidgetNarration(NarrationElementOutput output) { public void onPress() { onPress.accept(this); } - - public static class Icon { - private ResourceLocation texture; - private int offsetX, offsetY; - - public Icon(ResourceLocation texture, int offsetX, int offsetY) { - this.texture = texture; - this.offsetX = offsetX; - this.offsetY = offsetY; - } - } - } diff --git a/src/main/java/de/maxhenkel/pipez/gui/ExtractContainer.java b/src/main/java/de/maxhenkel/pipez/gui/ExtractContainer.java index cd0ae1a..ee0b2d7 100644 --- a/src/main/java/de/maxhenkel/pipez/gui/ExtractContainer.java +++ b/src/main/java/de/maxhenkel/pipez/gui/ExtractContainer.java @@ -2,9 +2,11 @@ import de.maxhenkel.corelib.inventory.ContainerBase; import de.maxhenkel.pipez.blocks.tileentity.PipeLogicTileEntity; +import de.maxhenkel.pipez.gui.sprite.ExtractUISprite; import net.minecraft.core.Direction; import net.minecraft.world.Container; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.Slot; public class ExtractContainer extends ContainerBase implements IPipeContainer { @@ -18,7 +20,7 @@ public ExtractContainer(int id, Container playerInventory, PipeLogicTileEntity p this.side = side; this.index = index; - addSlot(new UpgradeSlot(pipe.getUpgradeInventory(), side.get3DDataValue(), 9, 81)); + addSlot(new UpgradeSlot(pipe.getUpgradeInventory(), side.get3DDataValue(), ExtractUISprite.UPGRADE_SLOT.x, ExtractUISprite.UPGRADE_SLOT.y)); addPlayerInventorySlots(); } @@ -47,9 +49,24 @@ public int getInventorySize() { return 1; } + @Override + protected void addPlayerInventorySlots() { + if (playerInventory != null) { + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 9; j++) { + addSlot(new Slot(playerInventory, j + i * 9 + 9, 8 + j * 18 + ExtractUISprite.INVENTORY_OFFSET.x, 84 + i * 18 + ExtractUISprite.INVENTORY_OFFSET.y)); + } + } + + for (int k = 0; k < 9; k++) { + addSlot(new Slot(playerInventory, k, 8 + k * 18 + ExtractUISprite.INVENTORY_OFFSET.x, 142 + ExtractUISprite.INVENTORY_OFFSET.y)); + } + } + } + @Override public int getInvOffset() { - return 30; + return ExtractUISprite.INVENTORY_OFFSET.y; } @Override diff --git a/src/main/java/de/maxhenkel/pipez/gui/ExtractScreen.java b/src/main/java/de/maxhenkel/pipez/gui/ExtractScreen.java index 53604d7..43a465d 100644 --- a/src/main/java/de/maxhenkel/pipez/gui/ExtractScreen.java +++ b/src/main/java/de/maxhenkel/pipez/gui/ExtractScreen.java @@ -5,12 +5,15 @@ import de.maxhenkel.pipez.*; import de.maxhenkel.pipez.blocks.tileentity.PipeLogicTileEntity; import de.maxhenkel.pipez.blocks.tileentity.types.PipeType; +import de.maxhenkel.pipez.gui.sprite.ExtractElementsSprite; +import de.maxhenkel.pipez.gui.sprite.ExtractUISprite; +import de.maxhenkel.pipez.gui.sprite.SpriteRect; import de.maxhenkel.pipez.net.*; import de.maxhenkel.pipez.utils.GasUtils; import de.maxhenkel.pipez.utils.NbtUtils; import mekanism.api.chemical.ChemicalStack; +import net.minecraft.ChatFormatting; import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.Renderable; import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.narration.NarratableEntry; @@ -18,7 +21,6 @@ import net.minecraft.core.Direction; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvents; import net.minecraft.util.FormattedCharSequence; import net.minecraft.world.entity.player.Inventory; @@ -27,48 +29,55 @@ import net.neoforged.neoforge.fluids.FluidUtil; import net.neoforged.neoforge.network.PacketDistributor; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; +import java.util.*; import java.util.function.Supplier; public class ExtractScreen extends ScreenBase { - - public static final ResourceLocation BACKGROUND = ResourceLocation.fromNamespaceAndPath(Main.MODID, "textures/gui/container/extract.png"); + protected enum SORT_FILTER_LIST_TYPE { + NAME_ASC, NAME_DESC, DISTANCE_ASC, DISTANCE_DESC; + } private CycleIconButton redstoneButton; - private CycleIconButton sortButton; + private CycleIconButton distributionButton; private CycleIconButton filterButton; + private CycleIconButton sortFilterButton; - private Button addFilterButton; - private Button editFilterButton; - private Button removeFilterButton; + private IconButton addFilterButton; + private IconButton editFilterButton; + private IconButton removeFilterButton; private HoverArea redstoneArea; - private HoverArea sortArea; + private HoverArea distributionArea; private HoverArea filterArea; - + private HoverArea sortFilterArea; + private HoverArea addFilterArea; + private HoverArea editFilterArea; + private HoverArea deleteFilterArea; private HoverArea[] tabs; private PipeType[] pipeTypes; private int currentindex; + private int currentSortFilterListType; + + private static int currentSortFilterListTypeLast = 0; private FilterList filterList; public ExtractScreen(ExtractContainer container, Inventory playerInventory, Component title) { - super(BACKGROUND, container, playerInventory, title); - imageWidth = 176; - imageHeight = 196; + super(ExtractUISprite.IMAGE, container, playerInventory, title); + this.imageWidth = ExtractUISprite.SCREEN.w; + this.imageHeight = ExtractUISprite.SCREEN.h; - pipeTypes = container.getPipe().getPipeTypes(); - if (pipeTypes.length > 1) { - tabs = new HoverArea[pipeTypes.length]; + this.pipeTypes = container.getPipe().getPipeTypes(); + if (this.pipeTypes.length > 1) { + this.tabs = new HoverArea[pipeTypes.length]; } - currentindex = container.getIndex(); - if (currentindex < 0) { - currentindex = getMenu().getPipe().getPreferredPipeIndex(getMenu().getSide()); + this.currentindex = container.getIndex(); + if (this.currentindex < 0) { + this.currentindex = getMenu().getPipe().getPreferredPipeIndex(getMenu().getSide()); } + + this.currentSortFilterListType = ExtractScreen.currentSortFilterListTypeLast; } @Override @@ -80,48 +89,94 @@ protected void init() { PipeLogicTileEntity pipe = getMenu().getPipe(); Direction side = getMenu().getSide(); - filterList = new FilterList(this, 32, 8, 136, 66, () -> pipe.getFilters(side, pipeTypes[currentindex])); + filterList = new FilterList(this, ExtractUISprite.FILTER_LIST, ExtractUISprite.ROW_HEIGHT, ExtractUISprite.VISIBLE_ROW_COUNT, this::getSortedList); + // redstone button Supplier redstoneModeIndex = () -> pipe.getRedstoneMode(getMenu().getSide(), pipeTypes[currentindex]).ordinal(); - List redstoneModeIcons = Arrays.asList(new CycleIconButton.Icon(BACKGROUND, 176, 16), new CycleIconButton.Icon(BACKGROUND, 192, 16), new CycleIconButton.Icon(BACKGROUND, 208, 16), new CycleIconButton.Icon(BACKGROUND, 224, 16)); - redstoneButton = new CycleIconButton(leftPos + 7, topPos + 7, redstoneModeIcons, redstoneModeIndex, button -> { - PacketDistributor.sendToServer(new CycleRedstoneModeMessage(currentindex)); - }); + List redstoneModeIcons = Arrays.asList( + new IconButton.Icon(ExtractElementsSprite.IMAGE, ExtractElementsSprite.REDSTONE_MODE_ICON_IGNORE), + new IconButton.Icon(ExtractElementsSprite.IMAGE, ExtractElementsSprite.REDSTONE_MODE_ICON_OFF_WHEN_POWERED), + new IconButton.Icon(ExtractElementsSprite.IMAGE, ExtractElementsSprite.REDSTONE_MODE_ICON_ON_WHEN_POWERED), + new IconButton.Icon(ExtractElementsSprite.IMAGE, ExtractElementsSprite.REDSTONE_MODE_ICON_ALWAYS_OFF) + ); + redstoneButton = new CycleIconButton(this.leftPos + ExtractElementsSprite.REDSTONE_BUTTON.x, this.topPos + ExtractElementsSprite.REDSTONE_BUTTON.y, redstoneModeIcons, redstoneModeIndex, button -> PacketDistributor.sendToServer(new CycleRedstoneModeMessage(currentindex))); + + // distribution button Supplier distributionIndex = () -> pipe.getDistribution(getMenu().getSide(), pipeTypes[currentindex]).ordinal(); - List distributionIcons = Arrays.asList(new CycleIconButton.Icon(BACKGROUND, 176, 0), new CycleIconButton.Icon(BACKGROUND, 192, 0), new CycleIconButton.Icon(BACKGROUND, 208, 0), new CycleIconButton.Icon(BACKGROUND, 224, 0)); - sortButton = new CycleIconButton(leftPos + 7, topPos + 31, distributionIcons, distributionIndex, button -> { - PacketDistributor.sendToServer(new CycleDistributionMessage(currentindex)); - }); + List distributionIcons = Arrays.asList( + new IconButton.Icon(ExtractElementsSprite.IMAGE, ExtractElementsSprite.DISTRIBUTION_MODE_ICON_NEAREST), + new IconButton.Icon(ExtractElementsSprite.IMAGE, ExtractElementsSprite.DISTRIBUTION_MODE_ICON_FURTHEST), + new IconButton.Icon(ExtractElementsSprite.IMAGE, ExtractElementsSprite.DISTRIBUTION_MODE_ICON_ROUND_ROBIN), + new IconButton.Icon(ExtractElementsSprite.IMAGE, ExtractElementsSprite.DISTRIBUTION_MODE_ICON_RANDOM) + ); + distributionButton = new CycleIconButton(this.leftPos + ExtractElementsSprite.DISTRIBUTION_BUTTON.x, this.topPos + ExtractElementsSprite.DISTRIBUTION_BUTTON.y, distributionIcons, distributionIndex, button -> PacketDistributor.sendToServer(new CycleDistributionMessage(currentindex))); + + // filter mode button Supplier filterModeIndex = () -> pipeTypes[currentindex].hasFilter() ? pipe.getFilterMode(getMenu().getSide(), pipeTypes[currentindex]).ordinal() : 0; - List filterModeIcons = Arrays.asList(new CycleIconButton.Icon(BACKGROUND, 176, 32), new CycleIconButton.Icon(BACKGROUND, 192, 32)); - filterButton = new CycleIconButton(leftPos + 7, topPos + 55, filterModeIcons, filterModeIndex, button -> { - PacketDistributor.sendToServer(new CycleFilterModeMessage(currentindex)); - }); - addFilterButton = Button.builder(Component.translatable("message.pipez.filter.add"), button -> { - PacketDistributor.sendToServer(new EditFilterMessage(pipeTypes[currentindex].createFilter(), currentindex)); - }).bounds(leftPos + 31, topPos + 79, 40, 20).build(); - editFilterButton = Button.builder(Component.translatable("message.pipez.filter.edit"), button -> { - if (filterList.getSelected() >= 0) { - PacketDistributor.sendToServer(new EditFilterMessage(pipe.getFilters(side, pipeTypes[currentindex]).get(filterList.getSelected()), currentindex)); - } - }).bounds(leftPos + 80, topPos + 79, 40, 20).build(); - removeFilterButton = Button.builder(Component.translatable("message.pipez.filter.remove"), button -> { - if (filterList.getSelected() >= 0) { - PacketDistributor.sendToServer(new RemoveFilterMessage(pipe.getFilters(side, pipeTypes[currentindex]).get(filterList.getSelected()).getId(), currentindex)); - } - }).bounds(leftPos + 129, topPos + 79, 40, 20).build(); + List filterModeIcons = Arrays.asList( + new IconButton.Icon(ExtractElementsSprite.IMAGE, ExtractElementsSprite.FILTER_MODE_ICON_WHITELIST), + new IconButton.Icon(ExtractElementsSprite.IMAGE, ExtractElementsSprite.FILTER_MODE_ICON_BLACKLIST) + ); + filterButton = new CycleIconButton(this.leftPos + ExtractElementsSprite.FILTER_MODE_BUTTON.x, this.topPos + ExtractElementsSprite.FILTER_MODE_BUTTON.y, filterModeIcons, filterModeIndex, button -> PacketDistributor.sendToServer(new CycleFilterModeMessage(currentindex))); + + // sort filter list type + Supplier currentSortFilterListTypeIndex = () -> this.currentSortFilterListType; + List sortFilterIcons = Arrays.asList( + new IconButton.Icon(ExtractElementsSprite.IMAGE, ExtractElementsSprite.SORT_ICON_NAME_ASC), + new IconButton.Icon(ExtractElementsSprite.IMAGE, ExtractElementsSprite.SORT_ICON_NAME_DESC), + new IconButton.Icon(ExtractElementsSprite.IMAGE, ExtractElementsSprite.SORT_ICON_DISTANCE_ASC), + new IconButton.Icon(ExtractElementsSprite.IMAGE, ExtractElementsSprite.SORT_ICON_DISTANCE_DESC) + ); + sortFilterButton = new CycleIconButton( + this.leftPos + ExtractElementsSprite.SORT_FILTER_LIST_BUTTON.x, + this.topPos + ExtractElementsSprite.SORT_FILTER_LIST_BUTTON.y, + sortFilterIcons, + currentSortFilterListTypeIndex, + button -> { + this.currentSortFilterListType = this.currentSortFilterListType + 1 >= sortFilterIcons.size() ? 0 : this.currentSortFilterListType + 1; + ExtractScreen.currentSortFilterListTypeLast = this.currentSortFilterListType; + } + ); + + // Filter Entry Action Button + addFilterButton = new IconButton( + this.leftPos + ExtractElementsSprite.FILTER_ENTRY_BUTTON_ADD.x, this.topPos + ExtractElementsSprite.FILTER_ENTRY_BUTTON_ADD.y, + new IconButton.Icon(ExtractElementsSprite.IMAGE, ExtractElementsSprite.FILTER_ENTRY_ICON_ADD), + button -> PacketDistributor.sendToServer(new EditFilterMessage(pipeTypes[currentindex].createFilter(), currentindex)) + ); + editFilterButton = new IconButton( + this.leftPos + ExtractElementsSprite.FILTER_ENTRY_BUTTON_EDIT.x, this.topPos + ExtractElementsSprite.FILTER_ENTRY_BUTTON_EDIT.y, + new IconButton.Icon(ExtractElementsSprite.IMAGE, ExtractElementsSprite.FILTER_ENTRY_ICON_EDIT), + button -> { + if (filterList.getSelected() >= 0) { + PacketDistributor.sendToServer(new EditFilterMessage(pipe.getFilters(side, pipeTypes[currentindex]).get(filterList.getSelected()), currentindex)); + } + } + ); + removeFilterButton = new IconButton( + this.leftPos + ExtractElementsSprite.FILTER_ENTRY_BUTTON_DELETE.x, this.topPos + ExtractElementsSprite.FILTER_ENTRY_BUTTON_DELETE.y, + new IconButton.Icon(ExtractElementsSprite.IMAGE, ExtractElementsSprite.FILTER_ENTRY_ICON_DELETE), + button -> { + if (filterList.getSelected() >= 0) { + PacketDistributor.sendToServer(new RemoveFilterMessage(pipe.getFilters(side, pipeTypes[currentindex]).get(filterList.getSelected()).getId(), currentindex)); + } + } + ); + // render all buttons addRenderableWidget(redstoneButton); - addRenderableWidget(sortButton); + addRenderableWidget(distributionButton); addRenderableWidget(filterButton); + addRenderableWidget(sortFilterButton); addRenderableWidget(addFilterButton); addRenderableWidget(editFilterButton); addRenderableWidget(removeFilterButton); + // adding hover information for tabs, only available if more then one pipe type is used if (hasTabs()) { for (int i = 0; i < pipeTypes.length; i++) { int tabIndex = i; - tabs[i] = new HoverArea(-26 + 3, 5 + 25 * i, 24, 24, () -> { + tabs[i] = new HoverArea(ExtractElementsSprite.TAB_BUTTON.x, ExtractElementsSprite.TAB_BUTTON.y + (ExtractElementsSprite.TAB_BUTTON.h + ExtractElementsSprite.TAB_BUTTON_MARGIN) * i, ExtractElementsSprite.TAB_BUTTON.w, ExtractElementsSprite.TAB_BUTTON.h, () -> { List tooltip = new ArrayList<>(); tooltip.add(Component.translatable(pipeTypes[tabIndex].getTranslationKey()).getVisualOrderText()); return tooltip; @@ -130,30 +185,60 @@ protected void init() { } } - redstoneArea = new HoverArea(7, 7, 20, 20, () -> { + // define the hover area for tooltips on the buttons + redstoneArea = new HoverArea(ExtractElementsSprite.REDSTONE_BUTTON.x, ExtractElementsSprite.REDSTONE_BUTTON.y, ExtractElementsSprite.REDSTONE_BUTTON.w, ExtractElementsSprite.REDSTONE_BUTTON.h, () -> { if (redstoneButton.active) { return Arrays.asList(Component.translatable("tooltip.pipez.redstone_mode", Component.translatable("tooltip.pipez.redstone_mode." + pipe.getRedstoneMode(side, pipeTypes[currentindex]).getName())).getVisualOrderText()); } else { return Collections.emptyList(); } }); - sortArea = new HoverArea(7, 31, 20, 20, () -> { - if (sortButton.active) { + distributionArea = new HoverArea(ExtractElementsSprite.DISTRIBUTION_BUTTON.x, ExtractElementsSprite.DISTRIBUTION_BUTTON.y, ExtractElementsSprite.DISTRIBUTION_BUTTON.w, ExtractElementsSprite.DISTRIBUTION_BUTTON.h, () -> { + if (distributionButton.active) { return Arrays.asList(Component.translatable("tooltip.pipez.distribution", Component.translatable("tooltip.pipez.distribution." + pipe.getDistribution(side, pipeTypes[currentindex]).getName())).getVisualOrderText()); } else { return Collections.emptyList(); } }); - filterArea = new HoverArea(7, 55, 20, 20, () -> { + filterArea = new HoverArea(ExtractElementsSprite.FILTER_MODE_BUTTON.x, ExtractElementsSprite.FILTER_MODE_BUTTON.y, ExtractElementsSprite.FILTER_MODE_BUTTON.w, ExtractElementsSprite.FILTER_MODE_BUTTON.h, () -> { if (filterButton.active) { return Arrays.asList(Component.translatable("tooltip.pipez.filter_mode", Component.translatable("tooltip.pipez.filter_mode." + pipe.getFilterMode(side, pipeTypes[currentindex]).getName())).getVisualOrderText()); } else { return Collections.emptyList(); } }); + sortFilterArea = new HoverArea(ExtractElementsSprite.SORT_FILTER_LIST_BUTTON.x, ExtractElementsSprite.SORT_FILTER_LIST_BUTTON.y, ExtractElementsSprite.SORT_FILTER_LIST_BUTTON.w, ExtractElementsSprite.SORT_FILTER_LIST_BUTTON.h, + () -> Arrays.asList(Component.translatable("tooltip.pipez.sort_filter_list_mode", Component.translatable("tooltip.pipez.sort_filter_list_mode." + String.valueOf(this.currentSortFilterListType))).getVisualOrderText()) + ); + addFilterArea = new HoverArea(ExtractElementsSprite.FILTER_ENTRY_BUTTON_ADD.x, ExtractElementsSprite.FILTER_ENTRY_BUTTON_ADD.y, ExtractElementsSprite.FILTER_ENTRY_BUTTON_ADD.w, ExtractElementsSprite.FILTER_ENTRY_BUTTON_ADD.h, () -> { + if (filterButton.active) { + return Arrays.asList(Component.translatable("message.pipez.filter.add").getVisualOrderText()); + } else { + return Collections.emptyList(); + } + }); + editFilterArea = new HoverArea(ExtractElementsSprite.FILTER_ENTRY_BUTTON_EDIT.x, ExtractElementsSprite.FILTER_ENTRY_BUTTON_EDIT.y, ExtractElementsSprite.FILTER_ENTRY_BUTTON_EDIT.w, ExtractElementsSprite.FILTER_ENTRY_BUTTON_EDIT.h, () -> { + if (filterButton.active) { + return Arrays.asList(Component.translatable("message.pipez.filter.edit").getVisualOrderText()); + } else { + return Collections.emptyList(); + } + }); + deleteFilterArea = new HoverArea(ExtractElementsSprite.FILTER_ENTRY_BUTTON_DELETE.x, ExtractElementsSprite.FILTER_ENTRY_BUTTON_DELETE.y, ExtractElementsSprite.FILTER_ENTRY_BUTTON_DELETE.w, ExtractElementsSprite.FILTER_ENTRY_BUTTON_DELETE.h, () -> { + if (filterButton.active) { + return Arrays.asList(Component.translatable("message.pipez.filter.remove").getVisualOrderText()); + } else { + return Collections.emptyList(); + } + }); + hoverAreas.add(redstoneArea); - hoverAreas.add(sortArea); + hoverAreas.add(distributionArea); hoverAreas.add(filterArea); + hoverAreas.add(sortFilterArea); + hoverAreas.add(addFilterArea); + hoverAreas.add(editFilterArea); + hoverAreas.add(deleteFilterArea); checkButtons(); } @@ -168,7 +253,7 @@ protected void containerTick() { private void checkButtons() { Upgrade upgrade = getMenu().getPipe().getUpgrade(getMenu().getSide()); redstoneButton.active = Upgrade.canChangeRedstoneMode(upgrade); - sortButton.active = Upgrade.canChangeDistributionMode(upgrade); + distributionButton.active = Upgrade.canChangeDistributionMode(upgrade); filterButton.active = Upgrade.canChangeFilter(upgrade) && pipeTypes[currentindex].hasFilter(); addFilterButton.active = filterButton.active; editFilterButton.active = Upgrade.canChangeFilter(upgrade) && filterList.getSelected() >= 0; @@ -178,7 +263,7 @@ private void checkButtons() { @Override protected void renderLabels(GuiGraphics guiGraphics, int mouseX, int mouseY) { super.renderLabels(guiGraphics, mouseX, mouseY); - guiGraphics.drawString(font, playerInventoryTitle.getVisualOrderText(), 8F, (float) (imageHeight - 96 + 3), FONT_COLOR, false); + guiGraphics.drawString(font, playerInventoryTitle.getVisualOrderText(), (float) ExtractUISprite.INVENTORY_TITLE.x, (float) ExtractUISprite.INVENTORY_TITLE.y, FONT_COLOR, false); filterList.drawGuiContainerForegroundLayer(guiGraphics, mouseX, mouseY); @@ -192,30 +277,89 @@ protected void renderBg(GuiGraphics guiGraphics, float partialTicks, int mouseX, if (hasTabs()) { for (int i = 0; i < pipeTypes.length; i++) { + SpriteRect tabSpriteRect = ExtractElementsSprite.TAB_INACTIVE; if (i == currentindex) { - guiGraphics.blit(BACKGROUND, leftPos - 26 + 3, topPos + 5 + 25 * i, 176, 48, 26, 24); - } else { - guiGraphics.blit(BACKGROUND, leftPos - 26 + 3, topPos + 5 + 25 * i, 176, 72, 26, 24); + tabSpriteRect = ExtractElementsSprite.TAB_ACTIVE; } + guiGraphics.blit(ExtractElementsSprite.IMAGE, this.leftPos + ExtractElementsSprite.TAB_BUTTON.x, this.topPos + ExtractElementsSprite.TAB_BUTTON.y + (ExtractElementsSprite.TAB_BUTTON.h + ExtractElementsSprite.TAB_BUTTON_MARGIN) * i, tabSpriteRect.x, tabSpriteRect.y, tabSpriteRect.w, tabSpriteRect.h); } for (int i = 0; i < pipeTypes.length; i++) { if (i == currentindex) { - guiGraphics.renderItem(pipeTypes[i].getIcon(), leftPos - 26 + 3 + 4, topPos + 5 + 25 * i + 4, 0); - guiGraphics.renderItemDecorations(font, pipeTypes[i].getIcon(), leftPos - 26 + 3 + 4, topPos + 5 + 25 * i + 4); + guiGraphics.renderItem(pipeTypes[i].getIcon(), this.leftPos + ExtractElementsSprite.TAB_BUTTON_ICON_SELECTED.x, this.topPos + ExtractElementsSprite.TAB_BUTTON_ICON_SELECTED.y + (ExtractElementsSprite.TAB_BUTTON.h + ExtractElementsSprite.TAB_BUTTON_MARGIN) * i, 0); + guiGraphics.renderItemDecorations(font, pipeTypes[i].getIcon(), this.leftPos + ExtractElementsSprite.TAB_BUTTON_ICON_SELECTED.x, this.topPos + ExtractElementsSprite.TAB_BUTTON_ICON_SELECTED.y + (ExtractElementsSprite.TAB_BUTTON.h + ExtractElementsSprite.TAB_BUTTON_MARGIN) * i); } else { - guiGraphics.renderItem(pipeTypes[i].getIcon(), leftPos - 26 + 3 + 4 + 2, topPos + 5 + 25 * i + 4, 0); - guiGraphics.renderItemDecorations(font, pipeTypes[i].getIcon(), leftPos - 26 + 3 + 4 + 2, topPos + 5 + 25 * i + 4); + guiGraphics.renderItem(pipeTypes[i].getIcon(), this.leftPos + ExtractElementsSprite.TAB_BUTTON_ICON.x, this.topPos + ExtractElementsSprite.TAB_BUTTON_ICON.y + (ExtractElementsSprite.TAB_BUTTON.h + ExtractElementsSprite.TAB_BUTTON_MARGIN) * i, 0); + guiGraphics.renderItemDecorations(font, pipeTypes[i].getIcon(), this.leftPos + ExtractElementsSprite.TAB_BUTTON_ICON.x, this.topPos + ExtractElementsSprite.TAB_BUTTON_ICON.y + (ExtractElementsSprite.TAB_BUTTON.h + ExtractElementsSprite.TAB_BUTTON_MARGIN) * i); } } } } + protected List> getSortedList() { + PipeLogicTileEntity pipe = getMenu().getPipe(); + List> f = pipe.getFilters(getMenu().getSide(), pipeTypes[currentindex]); + + int sortDirection = this.currentSortFilterListType == SORT_FILTER_LIST_TYPE.NAME_ASC.ordinal() || this.currentSortFilterListType == SORT_FILTER_LIST_TYPE.DISTANCE_ASC.ordinal() ? 1 : -1; + + Comparator comparatorName = (filterA, filterB) -> filterA.getTranslatedName().withStyle(ChatFormatting.RESET).toString().compareTo(filterB.getTranslatedName().toString()) * sortDirection; + Comparator comparatorDistance = (filterA, filterB) -> { + if (filterA.hasDestination() == false && filterB.hasDestination() == false) { + return 0; + } + if (filterA.hasDestination() == true && filterB.hasDestination() == false) { + return -1; + } + if (filterA.hasDestination() == false && filterB.hasDestination() == true) { + return 1; + } + + // if name identical, compare by distance + //noinspection DataFlowIssue + int distanceA = filterA.getDistanceTo(pipe.getBlockPos()); + //noinspection DataFlowIssue + int distanceB = filterB.getDistanceTo(pipe.getBlockPos()); + if (distanceA < distanceB) { + return -1 * sortDirection; + } + if (distanceA > distanceB) { + return sortDirection; + } + + //noinspection DataFlowIssue + return filterA.getDestination().getDirection().getName().compareTo(filterB.getDestination().getDirection().getName()) * sortDirection; + }; + + List> comparators; + if (this.currentSortFilterListType == SORT_FILTER_LIST_TYPE.DISTANCE_ASC.ordinal() || this.currentSortFilterListType == SORT_FILTER_LIST_TYPE.DISTANCE_DESC.ordinal()) { + comparators = Arrays.asList(comparatorDistance, comparatorName); + } else { + comparators = Arrays.asList(comparatorName, comparatorDistance); + } + + f.sort((filterA, filterB) -> { + int i = 0; + while (i < comparators.size()) { + Comparator comparator = comparators.get(i); + int result = comparator.compare(filterA, filterB); + + if (result != 0) { + return result; + } + i++; + } + + return 0; + }); + + return f; + } + public int getTabsX() { - return leftPos - getTabsWidth(); + return this.leftPos - getTabsWidth(); } public int getTabsY() { - return topPos + 5; + return this.topPos + 5; } public int getTabsHeight() { @@ -242,7 +386,7 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) { if (hasTabs()) { for (int i = 0; i < tabs.length; i++) { HoverArea hoverArea = tabs[i]; - if (currentindex != i && hoverArea.isHovered(leftPos, topPos, (int) mouseX, (int) mouseY)) { + if (currentindex != i && hoverArea.isHovered(this.leftPos, this.topPos, (int) mouseX, (int) mouseY)) { minecraft.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1F)); currentindex = i; init(); diff --git a/src/main/java/de/maxhenkel/pipez/gui/FilterList.java b/src/main/java/de/maxhenkel/pipez/gui/FilterList.java index 33691da..d7c4113 100644 --- a/src/main/java/de/maxhenkel/pipez/gui/FilterList.java +++ b/src/main/java/de/maxhenkel/pipez/gui/FilterList.java @@ -4,68 +4,62 @@ import de.maxhenkel.corelib.CachedMap; import de.maxhenkel.corelib.helpers.AbstractStack; import de.maxhenkel.corelib.helpers.Pair; -import de.maxhenkel.corelib.helpers.WrappedFluidStack; -import de.maxhenkel.corelib.helpers.WrappedItemStack; import de.maxhenkel.corelib.inventory.ScreenBase; import de.maxhenkel.corelib.tag.SingleElementTag; -import de.maxhenkel.corelib.tag.Tag; import de.maxhenkel.pipez.DirectionalPosition; import de.maxhenkel.pipez.Filter; -import de.maxhenkel.pipez.utils.ComponentUtils; -import de.maxhenkel.pipez.Main; -import de.maxhenkel.pipez.utils.MekanismUtils; -import de.maxhenkel.pipez.utils.WrappedGasStack; +import de.maxhenkel.pipez.gui.sprite.ExtractElementsSprite; +import de.maxhenkel.pipez.gui.sprite.ExtractUISprite; +import de.maxhenkel.pipez.gui.sprite.SpriteRect; import net.minecraft.ChatFormatting; -import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Fluid; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; -import net.neoforged.neoforge.fluids.FluidStack; -import javax.annotation.Nullable; import java.util.ArrayList; import java.util.List; import java.util.function.Supplier; import java.util.stream.Collectors; public class FilterList extends WidgetBase { - - public static final ResourceLocation BACKGROUND = ResourceLocation.fromNamespaceAndPath(Main.MODID, "textures/gui/container/extract.png"); - protected Supplier>> filters; protected int offset; protected int selected; private ScreenBase.HoverArea[] hoverAreas; private ScreenBase.HoverArea[] itemHoverAreas; private ScreenBase.HoverArea[] blockHoverAreas; - private int columnHeight; - private int columnCount; + private int rowHeight; + private int rowCount; private CachedMap> filterPosCache; - public FilterList(ExtractScreen screen, int posX, int posY, int xSize, int ySize, Supplier>> filters) { - super(screen, posX, posY, xSize, ySize); + private static int offsetLast = 0; + private static int selectedLast = -1; + + public FilterList(ExtractScreen screen, SpriteRect rect, int rowHeight, int rowCount, Supplier>> filters) { + super(screen, rect.x, rect.y, rect.w, rect.h); + + this.rowHeight = rowHeight; + this.rowCount = rowCount; this.filters = filters; - columnHeight = 22; - columnCount = 3; - selected = -1; - hoverAreas = new ScreenBase.HoverArea[columnCount]; - itemHoverAreas = new ScreenBase.HoverArea[columnCount]; - blockHoverAreas = new ScreenBase.HoverArea[columnCount]; + this.offset = FilterList.offsetLast; + this.selected = FilterList.selectedLast; + + // TODO + hoverAreas = new ScreenBase.HoverArea[this.rowCount]; + itemHoverAreas = new ScreenBase.HoverArea[this.rowCount]; + blockHoverAreas = new ScreenBase.HoverArea[this.rowCount]; for (int i = 0; i < hoverAreas.length; i++) { - hoverAreas[i] = new ScreenBase.HoverArea(0, i * columnHeight, xSize, columnHeight); - itemHoverAreas[i] = new ScreenBase.HoverArea(3, 3 + i * columnHeight, 16, 16); - blockHoverAreas[i] = new ScreenBase.HoverArea(xSize - 3 - 16 - 11, 3 + i * columnHeight, 16, 16); + hoverAreas[i] = new ScreenBase.HoverArea(0, i * this.rowHeight, rect.w, this.rowHeight); + itemHoverAreas[i] = new ScreenBase.HoverArea(3, 3 + i * this.rowHeight, 16, 16); + blockHoverAreas[i] = new ScreenBase.HoverArea(rect.w - 3 - 16 - 11, 3 + i * this.rowHeight, 16, 16); } filterPosCache = new CachedMap<>(1000); @@ -75,13 +69,14 @@ public FilterList(ExtractScreen screen, int posX, int posY, int xSize, int ySize protected void drawGuiContainerForegroundLayer(GuiGraphics guiGraphics, int mouseX, int mouseY) { super.drawGuiContainerForegroundLayer(guiGraphics, mouseX, mouseY); List> f = filters.get(); + for (int i = 0; i < hoverAreas.length; i++) { if (getOffset() + i >= f.size()) { break; } Filter filter = f.get(getOffset() + i); if (itemHoverAreas[i].isHovered(guiLeft, guiTop, mouseX, mouseY)) { - AbstractStack stack = getStack(filter); + AbstractStack stack = filter.getStack(); if (stack != null && !stack.isEmpty()) { List tooltip = stack.getTooltip(); if (filter.isInvert()) { @@ -93,7 +88,7 @@ protected void drawGuiContainerForegroundLayer(GuiGraphics guiGraphics, int mous guiGraphics.renderTooltip(mc.font, tooltip.stream().map(Component::getVisualOrderText).collect(Collectors.toList()), mouseX - screen.getGuiLeft(), mouseY - screen.getGuiTop()); } } else if (blockHoverAreas[i].isHovered(guiLeft, guiTop, mouseX, mouseY)) { - if (filter.getDestination() != null) { + if (filter.hasDestination()) { List tooltip = new ArrayList<>(); Pair destPair = getBlockAt(filter.getDestination()); if (destPair.getKey() == null) { @@ -103,7 +98,7 @@ protected void drawGuiContainerForegroundLayer(GuiGraphics guiGraphics, int mous } BlockPos pos = filter.getDestination().getPos(); tooltip.add(Component.translatable("tooltip.pipez.filter.destination_location", number(pos.getX()), number(pos.getY()), number(pos.getZ()))); - tooltip.add(Component.translatable("tooltip.pipez.filter.destination_distance", number(pos.distManhattan(getContainer().getPipe().getBlockPos())))); + tooltip.add(Component.translatable("tooltip.pipez.filter.destination_distance", number(filter.getDistanceTo(getContainer().getPipe().getBlockPos())))); tooltip.add(Component.translatable("tooltip.pipez.filter.destination_side", Component.translatable("message.pipez.direction." + filter.getDestination().getDirection().getName()).withStyle(ChatFormatting.DARK_GREEN))); guiGraphics.renderTooltip(mc.font, tooltip.stream().map(Component::getVisualOrderText).collect(Collectors.toList()), mouseX - screen.getGuiLeft(), mouseY - screen.getGuiTop()); } @@ -115,56 +110,25 @@ private MutableComponent number(int num) { return Component.literal(String.valueOf(num)).withStyle(ChatFormatting.DARK_GREEN); } - @Nullable - public static AbstractStack getStack(Filter filter) { - Object o = null; - - if (filter.getTag() != null) { - o = get(filter.getTag()); - } - - if (o instanceof Item) { - ItemStack stack = new ItemStack((Item) o); - if (filter.getMetadata() != null) { - stack.applyComponents(ComponentUtils.getPatch(Minecraft.getInstance().level.registryAccess(), filter.getMetadata().copy())); - } - return new WrappedItemStack(stack); - } else if (o instanceof Fluid) { - FluidStack stack = new FluidStack((Fluid) o, 1000); - if (filter.getMetadata() != null) { - stack.applyComponents(ComponentUtils.getPatch(Minecraft.getInstance().level.registryAccess(), filter.getMetadata().copy())); - } - return new WrappedFluidStack(stack); - } - - if (MekanismUtils.isMekanismInstalled()) { - AbstractStack gasStack = WrappedGasStack.dummyStack(o); - if (gasStack != null) { - return gasStack; - } - } - - return null; - } - @Override protected void drawGuiContainerBackgroundLayer(GuiGraphics guiGraphics, float partialTicks, int mouseX, int mouseY) { super.drawGuiContainerBackgroundLayer(guiGraphics, partialTicks, mouseX, mouseY); List> f = filters.get(); - for (int i = getOffset(); i < f.size() && i < getOffset() + columnCount; i++) { + for (int i = getOffset(); i < f.size() && i < getOffset() + this.rowCount; i++) { RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.setShaderColor(1F, 1F, 1F, 1F); int pos = i - getOffset(); - int startY = guiTop + pos * columnHeight; - Filter filter = f.get(i); + int startY = guiTop + pos * this.rowHeight; + + SpriteRect entryImageSpriteRect = ExtractElementsSprite.FILTER_LIST_ENTRY; if (i == getSelected()) { - guiGraphics.blit(BACKGROUND, guiLeft, startY, 0, 218, 125, columnHeight, 256, 256); - } else { - guiGraphics.blit(BACKGROUND, guiLeft, startY, 0, 196, 125, columnHeight, 256, 256); + entryImageSpriteRect = ExtractElementsSprite.FILTER_LIST_ENTRY_SELECTED; } + guiGraphics.blit(ExtractElementsSprite.IMAGE, guiLeft, startY, entryImageSpriteRect.x, entryImageSpriteRect.y, entryImageSpriteRect.w, entryImageSpriteRect.h); - AbstractStack stack = getStack(filter); + Filter filter = f.get(i); + AbstractStack stack = filter.getStack(); if (stack != null && !stack.isEmpty()) { stack.render(guiGraphics, guiLeft + 3, startY + 3); if (filter.getTag() != null) { @@ -190,24 +154,32 @@ protected void drawGuiContainerBackgroundLayer(GuiGraphics guiGraphics, float pa drawStringSmall(guiGraphics, guiLeft + 22, startY + 15, Component.translatable("message.pipez.filter.inverted").withStyle(ChatFormatting.DARK_RED)); } - if (filter.getDestination() != null) { + if (filter.hasDestination()) { Pair dstPair = getBlockAt(filter.getDestination()); guiGraphics.renderItem(dstPair.getValue(), guiLeft + xSize - 3 - 16 - 11, startY + 3, 0); - guiGraphics.renderItemDecorations(mc.font, dstPair.getValue(), guiLeft + xSize - 3 - 16 - 11, startY + 3, String.valueOf(filter.getDestination().getDirection().name().charAt(0))); + + String distanceText = Component.translatable("message.pipez.filter.destination_distance", number(filter.getDistanceTo(getContainer().getPipe().getBlockPos()))).getString(); + guiGraphics.renderItemDecorations(mc.font, dstPair.getValue(), guiLeft + xSize - 3 - 16 - 11, startY - 7, distanceText); + + String directionText = Component.translatable("message.pipez.direction." + filter.getDestination().getDirection().getName()).getString(); + guiGraphics.renderItemDecorations(mc.font, dstPair.getValue(), guiLeft + xSize - 3 - 16 - 11, startY + 3, String.valueOf(directionText.charAt(0))); } } + drawStringSmall(guiGraphics, this.guiLeft + ExtractUISprite.ENTRY_COUNT_TEXT.x, this.guiTop + ExtractUISprite.ENTRY_COUNT_TEXT.y, Component.translatable("message.pipez.filter.entry_count", number(f.size()))); + RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.setShaderColor(1F, 1F, 1F, 1F); - if (f.size() > columnCount) { - float h = 66 - 17; - float perc = (float) getOffset() / (float) (f.size() - columnCount); - int posY = guiTop + (int) (h * perc); - guiGraphics.blit(BACKGROUND, guiLeft + xSize - 10, posY, 125, 196, 10, 17, 256, 256); - } else { - guiGraphics.blit(BACKGROUND, guiLeft + xSize - 10, guiTop, 135, 196, 10, 17, 256, 256); + SpriteRect scrollerImageSpriteRect = ExtractElementsSprite.FILTER_LIST_SCROLLER_INACTIVE; + int posY = guiTop; + if (f.size() > this.rowCount) { + float h = ExtractUISprite.ROW_HEIGHT * ExtractUISprite.VISIBLE_ROW_COUNT - ExtractElementsSprite.FILTER_LIST_SCROLLER_ACTIVE.h; + float perc = (float) getOffset() / (float) (f.size() - this.rowCount); + posY = guiTop + (int) (h * perc); + scrollerImageSpriteRect = ExtractElementsSprite.FILTER_LIST_SCROLLER_ACTIVE; } + guiGraphics.blit(ExtractElementsSprite.IMAGE, guiLeft + xSize - 10, posY, scrollerImageSpriteRect.x, scrollerImageSpriteRect.y, scrollerImageSpriteRect.w, scrollerImageSpriteRect.h); } private Pair getBlockAt(DirectionalPosition destination) { @@ -233,11 +205,12 @@ public void tick() { public int getOffset() { List> f = filters.get(); - if (f.size() <= columnCount) { + if (f.size() <= this.rowCount) { offset = 0; - } else if (offset > f.size() - columnCount) { - offset = f.size() - columnCount; + } else if (offset > f.size() - this.rowCount) { + offset = f.size() - this.rowCount; } + FilterList.offsetLast = offset; return offset; } @@ -245,6 +218,7 @@ public int getSelected() { if (selected >= filters.get().size()) { selected = -1; } + FilterList.selectedLast = selected; return selected; } @@ -256,21 +230,16 @@ private void drawStringSmall(GuiGraphics guiGraphics, int x, int y, Component te guiGraphics.pose().popPose(); } - public static T get(Tag tag) { - long time = Minecraft.getInstance().level.getGameTime(); - List allElements = tag.getAll().stream().toList(); - return allElements.get((int) (time / 20L % allElements.size())); - } - @Override public boolean mouseScrolled(double mouseX, double mouseY, double deltaX, double deltaY) { List> f = filters.get(); - if (f.size() > columnCount) { + if (f.size() > this.rowCount) { if (deltaY < 0D) { - offset = Math.min(getOffset() + 1, f.size() - columnCount); + offset = Math.min(getOffset() + 1, f.size() - this.rowCount); } else { offset = Math.max(getOffset() - 1, 0); } + FilterList.offsetLast = offset; return true; } return super.mouseScrolled(mouseX, mouseY, deltaX, deltaY); @@ -287,6 +256,7 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) { continue; } selected = getOffset() + i; + FilterList.selectedLast = selected; return true; } return super.mouseClicked(mouseX, mouseY, button); diff --git a/src/main/java/de/maxhenkel/pipez/gui/FilterScreen.java b/src/main/java/de/maxhenkel/pipez/gui/FilterScreen.java index 4e8c1c8..93fd16e 100644 --- a/src/main/java/de/maxhenkel/pipez/gui/FilterScreen.java +++ b/src/main/java/de/maxhenkel/pipez/gui/FilterScreen.java @@ -8,6 +8,7 @@ import de.maxhenkel.corelib.tag.Tag; import de.maxhenkel.corelib.tag.TagUtils; import de.maxhenkel.pipez.*; +import de.maxhenkel.pipez.gui.sprite.FilterSprite; import de.maxhenkel.pipez.items.FilterDestinationToolItem; import de.maxhenkel.pipez.net.OpenExtractMessage; import de.maxhenkel.pipez.net.UpdateFilterMessage; @@ -39,8 +40,6 @@ import java.util.stream.Collectors; public class FilterScreen extends ScreenBase { - public static final ResourceLocation BACKGROUND = ResourceLocation.fromNamespaceAndPath(Main.MODID, "textures/gui/container/filter.png"); - private EditBox item; private EditBox nbt; @@ -61,9 +60,9 @@ public class FilterScreen extends ScreenBase { private Filter filter; public FilterScreen(FilterContainer container, Inventory playerInventory, Component title) { - super(BACKGROUND, container, playerInventory, title); - imageWidth = 176; - imageHeight = 222; + super(FilterSprite.IMAGE, container, playerInventory, title); + imageWidth = FilterSprite.SCREEN.w; + imageHeight = FilterSprite.SCREEN.h; filter = getMenu().getFilter(); } @@ -74,12 +73,18 @@ protected void init() { hoverAreas.clear(); clearWidgets(); - List nbtIcons = Arrays.asList(new CycleIconButton.Icon(BACKGROUND, 176, 16), new CycleIconButton.Icon(BACKGROUND, 192, 16)); + List nbtIcons = Arrays.asList( + new IconButton.Icon(FilterSprite.IMAGE, FilterSprite.NBT_MODE_NOT_EXACT), + new IconButton.Icon(FilterSprite.IMAGE, FilterSprite.NBT_MODE_EXACT) + ); nbtButton = new CycleIconButton(leftPos + 125, topPos + 81, nbtIcons, () -> filter.isExactMetadata() ? 1 : 0, button -> { filter.setExactMetadata(!filter.isExactMetadata()); }); addRenderableWidget(nbtButton); - List invertIcons = Arrays.asList(new CycleIconButton.Icon(BACKGROUND, 176, 32), new CycleIconButton.Icon(BACKGROUND, 192, 32)); + List invertIcons = Arrays.asList( + new IconButton.Icon(FilterSprite.IMAGE, FilterSprite.INVERT_NO), + new IconButton.Icon(FilterSprite.IMAGE, FilterSprite.INVERT_YES) + ); invertButton = new CycleIconButton(leftPos + 149, topPos + 81, invertIcons, () -> filter.isInvert() ? 1 : 0, button -> { filter.setInvert(!filter.isInvert()); }); @@ -130,7 +135,7 @@ protected void init() { itemHoverArea = new HoverArea(8, 18, 16, 16, () -> { List tooltip = new ArrayList<>(); - AbstractStack stack = FilterList.getStack(filter); + AbstractStack stack = filter.getStack(); if (stack != null) { tooltip = stack.getTooltip(); if (filter.getTag() != null && !(filter.getTag() instanceof SingleElementTag)) { @@ -321,7 +326,7 @@ protected void renderLabels(GuiGraphics guiGraphics, int mouseX, int mouseY) { protected void renderBg(GuiGraphics guiGraphics, float partialTicks, int mouseX, int mouseY) { super.renderBg(guiGraphics, partialTicks, mouseX, mouseY); - AbstractStack stack = FilterList.getStack(filter); + AbstractStack stack = filter.getStack(); if (stack != null) { stack.render(guiGraphics, leftPos + 8, topPos + 18); } diff --git a/src/main/java/de/maxhenkel/pipez/gui/IconButton.java b/src/main/java/de/maxhenkel/pipez/gui/IconButton.java new file mode 100644 index 0000000..8201eea --- /dev/null +++ b/src/main/java/de/maxhenkel/pipez/gui/IconButton.java @@ -0,0 +1,53 @@ +package de.maxhenkel.pipez.gui; + +import com.mojang.blaze3d.systems.RenderSystem; +import de.maxhenkel.pipez.gui.sprite.SpriteRect; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.AbstractButton; +import net.minecraft.client.gui.narration.NarrationElementOutput; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; + +import java.util.function.Consumer; + +public class IconButton extends AbstractButton { + private Icon icon; + private Consumer onPress; + + public IconButton(int x, int y, Icon icon, Consumer onPress) { + // TODO ---> 20 + super(x, y, 20, 20, Component.empty()); + this.icon = icon; + this.onPress = onPress; + } + + @Override + public void renderWidget(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTicks) { + super.renderWidget(guiGraphics, mouseX, mouseY, partialTicks); + RenderSystem.setShader(GameRenderer::getPositionTexShader); + RenderSystem.setShaderColor(1F, 1F, 1F, 1F); + guiGraphics.blit(icon.texture, getX() + 2, getY() + 2, icon.spriteRect.x, icon.spriteRect.y, icon.spriteRect.w, icon.spriteRect.h); + } + + @Override + protected void updateWidgetNarration(NarrationElementOutput output) { + defaultButtonNarrationText(output); + } + + @Override + public void onPress() { + onPress.accept(this); + } + + public static class Icon { + public ResourceLocation texture; + public SpriteRect spriteRect; + + public Icon(ResourceLocation texture, SpriteRect spriteRect) { + this.texture = texture; + this.spriteRect = spriteRect; + } + } + +} diff --git a/src/main/java/de/maxhenkel/pipez/gui/sprite/ExtractElementsSprite.java b/src/main/java/de/maxhenkel/pipez/gui/sprite/ExtractElementsSprite.java new file mode 100644 index 0000000..448cf24 --- /dev/null +++ b/src/main/java/de/maxhenkel/pipez/gui/sprite/ExtractElementsSprite.java @@ -0,0 +1,58 @@ +package de.maxhenkel.pipez.gui.sprite; + +import de.maxhenkel.pipez.Main; +import net.minecraft.resources.ResourceLocation; + +public class ExtractElementsSprite { + public static ResourceLocation IMAGE = ResourceLocation.fromNamespaceAndPath(Main.MODID, "textures/gui/container/extract-elements.png"); + + public static SpriteRect FILTER_LIST_ENTRY = new SpriteRect(0, 96, 181, ExtractUISprite.ROW_HEIGHT); + public static SpriteRect FILTER_LIST_ENTRY_SELECTED = new SpriteRect(0, 118, 181, ExtractUISprite.ROW_HEIGHT); + + public static SpriteRect FILTER_LIST_SCROLLER_ACTIVE = new SpriteRect(0, 172, 10, 17); + public static SpriteRect FILTER_LIST_SCROLLER_INACTIVE = new SpriteRect(10, 172, 10, 17); + + private static int ICON_BUTTON_WIDTH = 16; + private static int ICON_BUTTON_HEIGHT = 16; + + public static SpriteRect REDSTONE_MODE_ICON_IGNORE = new SpriteRect(0, 16, ICON_BUTTON_WIDTH, ICON_BUTTON_HEIGHT); + public static SpriteRect REDSTONE_MODE_ICON_OFF_WHEN_POWERED = new SpriteRect(16, 16, ICON_BUTTON_WIDTH, ICON_BUTTON_HEIGHT); + public static SpriteRect REDSTONE_MODE_ICON_ON_WHEN_POWERED = new SpriteRect(32, 16, ICON_BUTTON_WIDTH, ICON_BUTTON_HEIGHT); + public static SpriteRect REDSTONE_MODE_ICON_ALWAYS_OFF = new SpriteRect(48, 16, ICON_BUTTON_WIDTH, ICON_BUTTON_HEIGHT); + + public static SpriteRect DISTRIBUTION_MODE_ICON_NEAREST = new SpriteRect(0, 0, ICON_BUTTON_WIDTH, ICON_BUTTON_HEIGHT); + public static SpriteRect DISTRIBUTION_MODE_ICON_FURTHEST = new SpriteRect(16, 0, ICON_BUTTON_WIDTH, ICON_BUTTON_HEIGHT); + public static SpriteRect DISTRIBUTION_MODE_ICON_ROUND_ROBIN = new SpriteRect(32, 0, ICON_BUTTON_WIDTH, ICON_BUTTON_HEIGHT); + public static SpriteRect DISTRIBUTION_MODE_ICON_RANDOM = new SpriteRect(48, 0, ICON_BUTTON_WIDTH, ICON_BUTTON_HEIGHT); + + public static SpriteRect FILTER_MODE_ICON_WHITELIST = new SpriteRect(0, 32, ICON_BUTTON_WIDTH, ICON_BUTTON_HEIGHT); + public static SpriteRect FILTER_MODE_ICON_BLACKLIST = new SpriteRect(16, 32, ICON_BUTTON_WIDTH, ICON_BUTTON_HEIGHT); + + public static SpriteRect SORT_ICON_NAME_ASC = new SpriteRect(0, 156, ICON_BUTTON_WIDTH, ICON_BUTTON_HEIGHT); + public static SpriteRect SORT_ICON_NAME_DESC = new SpriteRect(SORT_ICON_NAME_ASC.x + SORT_ICON_NAME_ASC.w, SORT_ICON_NAME_ASC.y, ICON_BUTTON_WIDTH, ICON_BUTTON_HEIGHT); + public static SpriteRect SORT_ICON_DISTANCE_ASC = new SpriteRect(SORT_ICON_NAME_DESC.x + SORT_ICON_NAME_DESC.w, SORT_ICON_NAME_ASC.y, ICON_BUTTON_WIDTH, ICON_BUTTON_HEIGHT); + public static SpriteRect SORT_ICON_DISTANCE_DESC = new SpriteRect(SORT_ICON_DISTANCE_ASC.x + SORT_ICON_DISTANCE_ASC.w, SORT_ICON_NAME_ASC.y, ICON_BUTTON_WIDTH, ICON_BUTTON_HEIGHT); + + public static SpriteRect FILTER_ENTRY_ICON_ADD = new SpriteRect(0, 140, ICON_BUTTON_WIDTH, ICON_BUTTON_HEIGHT); + public static SpriteRect FILTER_ENTRY_ICON_DELETE = new SpriteRect(16, 140, ICON_BUTTON_WIDTH, ICON_BUTTON_HEIGHT); + public static SpriteRect FILTER_ENTRY_ICON_EDIT = new SpriteRect(32, 140, ICON_BUTTON_WIDTH, ICON_BUTTON_HEIGHT); + + public static SpriteRect TAB_ACTIVE = new SpriteRect(0, 48, 26, 24); + public static SpriteRect TAB_INACTIVE = new SpriteRect(0, 72, 26, 24); + + public static int BUTTON_MARGIN = 2; + public static SpriteRect REDSTONE_BUTTON = new SpriteRect(7, 7, 20, 20); + public static SpriteRect DISTRIBUTION_BUTTON = new SpriteRect(7, REDSTONE_BUTTON.y + REDSTONE_BUTTON.h + BUTTON_MARGIN, 20, 20); + public static SpriteRect FILTER_MODE_BUTTON = new SpriteRect(7, DISTRIBUTION_BUTTON.y + DISTRIBUTION_BUTTON.h + BUTTON_MARGIN, 20, 20); + + public static SpriteRect SORT_FILTER_LIST_BUTTON = new SpriteRect(229, 7, 20, 20); + + public static SpriteRect FILTER_ENTRY_BUTTON_ADD = new SpriteRect(229, 99, 20, 20); + public static SpriteRect FILTER_ENTRY_BUTTON_EDIT = new SpriteRect(229, FILTER_ENTRY_BUTTON_ADD.y + FILTER_ENTRY_BUTTON_ADD.h + BUTTON_MARGIN, 20, 20); + public static SpriteRect FILTER_ENTRY_BUTTON_DELETE = new SpriteRect(229, FILTER_ENTRY_BUTTON_EDIT.y + FILTER_ENTRY_BUTTON_EDIT.h + BUTTON_MARGIN, 20, 20); + + public static int TAB_BUTTON_MARGIN = 1; + public static SpriteRect TAB_BUTTON = new SpriteRect(-26 + 3, 5, 24, 24); + public static SpritePosition TAB_BUTTON_ICON_SELECTED = new SpritePosition(TAB_BUTTON.x + 4, TAB_BUTTON.y + 4); + public static SpritePosition TAB_BUTTON_ICON = new SpritePosition(TAB_BUTTON_ICON_SELECTED.x + 2, TAB_BUTTON_ICON_SELECTED.y); +} diff --git a/src/main/java/de/maxhenkel/pipez/gui/sprite/ExtractUISprite.java b/src/main/java/de/maxhenkel/pipez/gui/sprite/ExtractUISprite.java new file mode 100644 index 0000000..9de72cd --- /dev/null +++ b/src/main/java/de/maxhenkel/pipez/gui/sprite/ExtractUISprite.java @@ -0,0 +1,21 @@ +package de.maxhenkel.pipez.gui.sprite; + +import de.maxhenkel.pipez.Main; +import net.minecraft.resources.ResourceLocation; + +public class ExtractUISprite { + public static ResourceLocation IMAGE = ResourceLocation.fromNamespaceAndPath(Main.MODID, "textures/gui/container/extract-ui.png"); + + public static int ROW_HEIGHT = 22; + public static int VISIBLE_ROW_COUNT = 7; + + public static SpriteRect SCREEN = new SpriteRect(0, 0, 256, 256); + public static SpriteRect FILTER_LIST = new SpriteRect(32, 8, 192, ROW_HEIGHT * VISIBLE_ROW_COUNT); + + public static SpritePosition ENTRY_COUNT_TEXT = new SpritePosition(32 - FILTER_LIST.x, 3 - FILTER_LIST.y); // relative to Filter List + public static SpritePosition INVENTORY_TITLE = new SpritePosition(47, 164); + public static SpritePosition UPGRADE_SLOT = new SpritePosition(9, 146); + // x starts at 8 + // y starts at 84 + public static SpritePosition INVENTORY_OFFSET = new SpritePosition(48 - 8, 174 - 84); +} diff --git a/src/main/java/de/maxhenkel/pipez/gui/sprite/FilterSprite.java b/src/main/java/de/maxhenkel/pipez/gui/sprite/FilterSprite.java new file mode 100644 index 0000000..e5e7107 --- /dev/null +++ b/src/main/java/de/maxhenkel/pipez/gui/sprite/FilterSprite.java @@ -0,0 +1,19 @@ +package de.maxhenkel.pipez.gui.sprite; + +import de.maxhenkel.pipez.Main; +import net.minecraft.resources.ResourceLocation; + +public class FilterSprite { + public static ResourceLocation IMAGE = ResourceLocation.fromNamespaceAndPath(Main.MODID, "textures/gui/container/filter.png"); + + public static SpriteRect SCREEN = new SpriteRect(0, 0, 176,222); + + private static int ICON_BUTTON_WIDTH = 16; + private static int ICON_BUTTON_HEIGHT = 16; + + public static SpriteRect NBT_MODE_NOT_EXACT = new SpriteRect(176, 16, ICON_BUTTON_WIDTH, ICON_BUTTON_HEIGHT); + public static SpriteRect NBT_MODE_EXACT = new SpriteRect(192, 16, ICON_BUTTON_WIDTH, ICON_BUTTON_HEIGHT); + + public static SpriteRect INVERT_NO = new SpriteRect(176, 32, ICON_BUTTON_WIDTH, ICON_BUTTON_HEIGHT); + public static SpriteRect INVERT_YES = new SpriteRect(192, 32, ICON_BUTTON_WIDTH, ICON_BUTTON_HEIGHT); +} diff --git a/src/main/java/de/maxhenkel/pipez/gui/sprite/SpritePosition.java b/src/main/java/de/maxhenkel/pipez/gui/sprite/SpritePosition.java new file mode 100644 index 0000000..05e3dfc --- /dev/null +++ b/src/main/java/de/maxhenkel/pipez/gui/sprite/SpritePosition.java @@ -0,0 +1,9 @@ +package de.maxhenkel.pipez.gui.sprite; + +public class SpritePosition { + public int x; + public int y; + public SpritePosition(int x, int y) { + this.x = x; + this.y = y; + }} diff --git a/src/main/java/de/maxhenkel/pipez/gui/sprite/SpriteRect.java b/src/main/java/de/maxhenkel/pipez/gui/sprite/SpriteRect.java new file mode 100644 index 0000000..252c787 --- /dev/null +++ b/src/main/java/de/maxhenkel/pipez/gui/sprite/SpriteRect.java @@ -0,0 +1,12 @@ +package de.maxhenkel.pipez.gui.sprite; + +public class SpriteRect extends SpritePosition { + public int w; + public int h; + + public SpriteRect(int x, int y, int w, int h) { + super(x, y); + this.w = w; + this.h = h; + } +} diff --git a/src/main/resources/assets/pipez/lang/cs_cz.json b/src/main/resources/assets/pipez/lang/cs_cz.json index 7cbe4fa..c0d6a64 100644 --- a/src/main/resources/assets/pipez/lang/cs_cz.json +++ b/src/main/resources/assets/pipez/lang/cs_cz.json @@ -82,5 +82,11 @@ "message.pipez.filter_destination_tool.destination": "Destinace: %s, %s, %s, %s", "message.pipez.filter_destination_tool.destination.any": "Destinace: Různá", "message.pipez.filter_destination_tool.destination.set": "Destinace nastavena", - "config.jade.plugin_pipez.pipe": "Trubka" - } + "config.jade.plugin_pipez.pipe": "Trubka", + "tooltip.pipez.sort_filter_list_mode": "Řadit podle: %s", + "tooltip.pipez.sort_filter_list_mode.0": "Jméno vzestupně", + "tooltip.pipez.sort_filter_list_mode.1": "Jméno sestupně", + "tooltip.pipez.sort_filter_list_mode.2": "Vzdálenost vzestupně", + "tooltip.pipez.sort_filter_list_mode.3": "Vzdálenost klesající", + "message.pipez.filter.entry_count": "Příspěvky: %s" +} diff --git a/src/main/resources/assets/pipez/lang/de_de.json b/src/main/resources/assets/pipez/lang/de_de.json index 6903bd3..58470ce 100644 --- a/src/main/resources/assets/pipez/lang/de_de.json +++ b/src/main/resources/assets/pipez/lang/de_de.json @@ -81,5 +81,11 @@ "message.pipez.filter.destination": "Ziel", "message.pipez.filter_destination_tool.destination": "Ziel: %s, %s, %s, %s", "message.pipez.filter_destination_tool.destination.any": "Ziel: alle", - "message.pipez.filter_destination_tool.destination.set": "Ziel gesetzt" + "message.pipez.filter_destination_tool.destination.set": "Ziel gesetzt", + "tooltip.pipez.sort_filter_list_mode": "Sortierung nach: %s", + "tooltip.pipez.sort_filter_list_mode.0": "Name aufsteigend", + "tooltip.pipez.sort_filter_list_mode.1": "Name absteigend", + "tooltip.pipez.sort_filter_list_mode.2": "Entfernung aufsteigend", + "tooltip.pipez.sort_filter_list_mode.3": "Entfernung absteigend", + "message.pipez.filter.entry_count": "Einträge: %s" } \ No newline at end of file diff --git a/src/main/resources/assets/pipez/lang/en_us.json b/src/main/resources/assets/pipez/lang/en_us.json index 7acc63f..08f8647 100644 --- a/src/main/resources/assets/pipez/lang/en_us.json +++ b/src/main/resources/assets/pipez/lang/en_us.json @@ -72,6 +72,7 @@ "message.pipez.direction.up": "Up", "message.pipez.direction.down": "Down", "message.pipez.filter.add": "Add", + "message.pipez.filter.destination_distance": "%s", "message.pipez.filter.edit": "Edit", "message.pipez.filter.remove": "Remove", "message.pipez.filter.cancel": "Cancel", @@ -82,5 +83,11 @@ "message.pipez.filter_destination_tool.destination": "Destination: %s, %s, %s, %s", "message.pipez.filter_destination_tool.destination.any": "Destination: Any", "message.pipez.filter_destination_tool.destination.set": "Destination set", - "config.jade.plugin_pipez.pipe": "Pipe" + "config.jade.plugin_pipez.pipe": "Pipe", + "tooltip.pipez.sort_filter_list_mode": "Sort by: %s", + "tooltip.pipez.sort_filter_list_mode.0": "Name ascending", + "tooltip.pipez.sort_filter_list_mode.1": "Name descending", + "tooltip.pipez.sort_filter_list_mode.2": "Distance ascending", + "tooltip.pipez.sort_filter_list_mode.3": "Distance descending", + "message.pipez.filter.entry_count": "Entries: %s" } \ No newline at end of file diff --git a/src/main/resources/assets/pipez/lang/fr_fr.json b/src/main/resources/assets/pipez/lang/fr_fr.json index 567947e..ceca517 100644 --- a/src/main/resources/assets/pipez/lang/fr_fr.json +++ b/src/main/resources/assets/pipez/lang/fr_fr.json @@ -82,5 +82,11 @@ "message.pipez.filter_destination_tool.destination": "Destination: %s, %s, %s, %s", "message.pipez.filter_destination_tool.destination.any": "Destination: toute", "message.pipez.filter_destination_tool.destination.set": "Destination définie", - "config.jade.plugin_pipez.pipe": "Pipe" + "config.jade.plugin_pipez.pipe": "Pipe", + "tooltip.pipez.sort_filter_list_mode": "Trier par : %s", + "tooltip.pipez.sort_filter_list_mode.0": "Nom croissant", + "tooltip.pipez.sort_filter_list_mode.1": "Nom décroissant", + "tooltip.pipez.sort_filter_list_mode.2": "Distance croissante", + "tooltip.pipez.sort_filter_list_mode.3": "Distance décroissante", + "message.pipez.filter.entry_count": "Entrées: %s" } diff --git a/src/main/resources/assets/pipez/lang/it_it.json b/src/main/resources/assets/pipez/lang/it_it.json index 3dc40ad..7a87356 100644 --- a/src/main/resources/assets/pipez/lang/it_it.json +++ b/src/main/resources/assets/pipez/lang/it_it.json @@ -81,6 +81,12 @@ "message.pipez.filter.destination": "Destinazione", "message.pipez.filter_destination_tool.destination": "Destinazione: %s, %s, %s, %s", "message.pipez.filter_destination_tool.destination.any": "Qualsiasi destinazione", - "message.pipez.filter_destination_tool.destination.set": "Destinazione impostata" - "config.jade.plugin_pipez.pipe": "Tubo" + "message.pipez.filter_destination_tool.destination.set": "Destinazione impostata", + "config.jade.plugin_pipez.pipe": "Tubo", + "tooltip.pipez.sort_filter_list_mode": "Ordina per: %s", + "tooltip.pipez.sort_filter_list_mode.0": "Nome crescente", + "tooltip.pipez.sort_filter_list_mode.1": "Nome decrescente", + "tooltip.pipez.sort_filter_list_mode.2": "Distanza crescente", + "tooltip.pipez.sort_filter_list_mode.3": "Distanza decrescente", + "message.pipez.filter.entry_count": "Voci: %s" } diff --git a/src/main/resources/assets/pipez/lang/ja_jp.json b/src/main/resources/assets/pipez/lang/ja_jp.json index 7845fbf..ebcb140 100644 --- a/src/main/resources/assets/pipez/lang/ja_jp.json +++ b/src/main/resources/assets/pipez/lang/ja_jp.json @@ -82,5 +82,11 @@ "message.pipez.filter_destination_tool.destination": "目的地:%s, %s, %s, %s", "message.pipez.filter_destination_tool.destination.any": "目的地:任意", "message.pipez.filter_destination_tool.destination.set": "目的地を設定しました", - "config.jade.plugin_pipez.pipe": "パイプ" + "config.jade.plugin_pipez.pipe": "パイプ", + "tooltip.pipez.sort_filter_list_mode": "並べ替え: %s", + "tooltip.pipez.sort_filter_list_mode.0": "名前昇順", + "tooltip.pipez.sort_filter_list_mode.1": "名前降順", + "tooltip.pipez.sort_filter_list_mode.2": "距離昇順", + "tooltip.pipez.sort_filter_list_mode.3": "距離降順", + "message.pipez.filter.entry_count": "エントリー: %s" } diff --git a/src/main/resources/assets/pipez/lang/ko_kr.json b/src/main/resources/assets/pipez/lang/ko_kr.json index 0395609..4813217 100644 --- a/src/main/resources/assets/pipez/lang/ko_kr.json +++ b/src/main/resources/assets/pipez/lang/ko_kr.json @@ -81,5 +81,11 @@ "message.pipez.filter.destination": "목적지", "message.pipez.filter_destination_tool.destination": "목적지: %s, %s, %s, %s", "message.pipez.filter_destination_tool.destination.any": "목적지: 아무데나", - "message.pipez.filter_destination_tool.destination.set": "목적지 설정" + "message.pipez.filter_destination_tool.destination.set": "목적지 설정", + "tooltip.pipez.sort_filter_list_mode": "정렬 기준: %s", + "tooltip.pipez.sort_filter_list_mode.0": "이름 오름차순", + "tooltip.pipez.sort_filter_list_mode.1": "이름 내림차순", + "tooltip.pipez.sort_filter_list_mode.2": "거리 오름차순", + "tooltip.pipez.sort_filter_list_mode.3": "거리 내림차순", + "message.pipez.filter.entry_count": "항목: %s" } diff --git a/src/main/resources/assets/pipez/lang/pt_br.json b/src/main/resources/assets/pipez/lang/pt_br.json index e0c7d43..4b20fbd 100644 --- a/src/main/resources/assets/pipez/lang/pt_br.json +++ b/src/main/resources/assets/pipez/lang/pt_br.json @@ -82,5 +82,11 @@ "message.pipez.filter_destination_tool.destination": "Destino: %s, %s, %s, %s", "message.pipez.filter_destination_tool.destination.any": "Destino: qualquer", "message.pipez.filter_destination_tool.destination.set": "Destino definido", - "config.jade.plugin_pipez.pipe": "Estatísticas do tubo" + "config.jade.plugin_pipez.pipe": "Estatísticas do tubo", + "tooltip.pipez.sort_filter_list_mode": "Classificar por: %s", + "tooltip.pipez.sort_filter_list_mode.0": "Nome ascendente", + "tooltip.pipez.sort_filter_list_mode.1": "Nome descendente", + "tooltip.pipez.sort_filter_list_mode.2": "Distância ascendente", + "tooltip.pipez.sort_filter_list_mode.3": "Distância descendente", + "message.pipez.filter.entry_count": "Entradas: %s" } \ No newline at end of file diff --git a/src/main/resources/assets/pipez/lang/ru_ru.json b/src/main/resources/assets/pipez/lang/ru_ru.json index afcc5ed..bc96edd 100644 --- a/src/main/resources/assets/pipez/lang/ru_ru.json +++ b/src/main/resources/assets/pipez/lang/ru_ru.json @@ -82,5 +82,11 @@ "message.pipez.filter_destination_tool.destination": "Место назначения: %s, %s, %s, %s", "message.pipez.filter_destination_tool.destination.any": "Место назначения: Любое", "message.pipez.filter_destination_tool.destination.set": "Место назначения установлено", - "config.jade.plugin_pipez.pipe": "Труба" + "config.jade.plugin_pipez.pipe": "Труба", + "tooltip.pipez.sort_filter_list_mode": "Сортировать по: %s", + "tooltip.pipez.sort_filter_list_mode.0": "Имя по возрастанию", + "tooltip.pipez.sort_filter_list_mode.1": "Имя по убыванию", + "tooltip.pipez.sort_filter_list_mode.2": "Расстояние по возрастанию", + "tooltip.pipez.sort_filter_list_mode.3": "Расстояние по убыванию", + "message.pipez.filter.entry_count": "Записи: %s" } diff --git a/src/main/resources/assets/pipez/lang/sv_se.json b/src/main/resources/assets/pipez/lang/sv_se.json index 4918888..650237f 100644 --- a/src/main/resources/assets/pipez/lang/sv_se.json +++ b/src/main/resources/assets/pipez/lang/sv_se.json @@ -81,5 +81,11 @@ "message.pipez.filter.destination": "Destination", "message.pipez.filter_destination_tool.destination": "Destination: %s, %s, %s, %s", "message.pipez.filter_destination_tool.destination.any": "Destination: Var som helst", - "message.pipez.filter_destination_tool.destination.set": "Destination har angivits" + "message.pipez.filter_destination_tool.destination.set": "Destination har angivits", + "tooltip.pipez.sort_filter_list_mode": "Sortera efter: %s", + "tooltip.pipez.sort_filter_list_mode.0": "Namn stigande", + "tooltip.pipez.sort_filter_list_mode.1": "Namn fallande", + "tooltip.pipez.sort_filter_list_mode.2": "Avstånd stigande", + "tooltip.pipez.sort_filter_list_mode.3": "Avståndet faller", + "message.pipez.filter.entry_count": "Inlägg: %s" } diff --git a/src/main/resources/assets/pipez/lang/tr_tr.json b/src/main/resources/assets/pipez/lang/tr_tr.json index 3a71ee2..352397b 100644 --- a/src/main/resources/assets/pipez/lang/tr_tr.json +++ b/src/main/resources/assets/pipez/lang/tr_tr.json @@ -82,5 +82,11 @@ "message.pipez.filter_destination_tool.destination": "Hedef: %s, %s, %s, %s", "message.pipez.filter_destination_tool.destination.any": "Hedef: Herhangi", "message.pipez.filter_destination_tool.destination.set": "Hedef girildi", - "config.jade.plugin_pipez.pipe": "Boru" + "config.jade.plugin_pipez.pipe": "Boru", + "tooltip.pipez.sort_filter_list_mode": "Sıralama: %s", + "tooltip.pipez.sort_filter_list_mode.0": "İsim artan", + "tooltip.pipez.sort_filter_list_mode.1": "İsim azalan", + "tooltip.pipez.sort_filter_list_mode.2": "Mesafe artan", + "tooltip.pipez.sort_filter_list_mode.3": "Mesafe azalan", + "message.pipez.filter.entry_count": "Girişler: %s" } \ No newline at end of file diff --git a/src/main/resources/assets/pipez/lang/uk_ua.json b/src/main/resources/assets/pipez/lang/uk_ua.json index 7b0be6f..fca6835 100644 --- a/src/main/resources/assets/pipez/lang/uk_ua.json +++ b/src/main/resources/assets/pipez/lang/uk_ua.json @@ -82,5 +82,11 @@ "message.pipez.filter_destination_tool.destination": "Призначення: %s, %s, %s, %s", "message.pipez.filter_destination_tool.destination.any": "Призначення: Будь-яке", "message.pipez.filter_destination_tool.destination.set": "Призначення встановлене", - "config.jade.plugin_pipez.pipe": "Труба" + "config.jade.plugin_pipez.pipe": "Труба", + "tooltip.pipez.sort_filter_list_mode": "Сортувати за: %s", + "tooltip.pipez.sort_filter_list_mode.0": "Назва за зростанням", + "tooltip.pipez.sort_filter_list_mode.1": "Назва за спаданням", + "tooltip.pipez.sort_filter_list_mode.2": "Відстань по зростанню", + "tooltip.pipez.sort_filter_list_mode.3": "Відстань зниження", + "message.pipez.filter.entry_count": "Записи: %s" } \ No newline at end of file diff --git a/src/main/resources/assets/pipez/lang/zh_cn.json b/src/main/resources/assets/pipez/lang/zh_cn.json index 3a8d8ce..6c2b11e 100644 --- a/src/main/resources/assets/pipez/lang/zh_cn.json +++ b/src/main/resources/assets/pipez/lang/zh_cn.json @@ -82,5 +82,11 @@ "message.pipez.filter_destination_tool.destination": "目标:%s,%s,%s,%s", "message.pipez.filter_destination_tool.destination.any": "目标:任何", "message.pipez.filter_destination_tool.destination.set": "目标已设定", - "config.jade.plugin_pipez.pipe": "管道" - } \ No newline at end of file + "config.jade.plugin_pipez.pipe": "管道", + "tooltip.pipez.sort_filter_list_mode": "排序依据:%s", + "tooltip.pipez.sort_filter_list_mode.0": "名称升序", + "tooltip.pipez.sort_filter_list_mode.1": "名称降序", + "tooltip.pipez.sort_filter_list_mode.2": "距离升序", + "tooltip.pipez.sort_filter_list_mode.3": "距离降序", + "message.pipez.filter.entry_count": "条目: %s" +} \ No newline at end of file diff --git a/src/main/resources/assets/pipez/textures/gui/container/extract-elements.png b/src/main/resources/assets/pipez/textures/gui/container/extract-elements.png new file mode 100644 index 0000000..044456d Binary files /dev/null and b/src/main/resources/assets/pipez/textures/gui/container/extract-elements.png differ diff --git a/src/main/resources/assets/pipez/textures/gui/container/extract-ui.png b/src/main/resources/assets/pipez/textures/gui/container/extract-ui.png new file mode 100644 index 0000000..e5ab46e Binary files /dev/null and b/src/main/resources/assets/pipez/textures/gui/container/extract-ui.png differ diff --git a/src/main/resources/assets/pipez/textures/gui/container/extract.png b/src/main/resources/assets/pipez/textures/gui/container/extract.png deleted file mode 100644 index d44c9d6..0000000 Binary files a/src/main/resources/assets/pipez/textures/gui/container/extract.png and /dev/null differ