From fab7b9b35449a1e93bd3e2a9b3039079fa72bd20 Mon Sep 17 00:00:00 2001 From: Raven Szewczyk Date: Sun, 26 Jun 2022 08:56:10 +0100 Subject: [PATCH] Conduit gui 1.12.2 backport (#74) * Update EnderCore * Backport BaseSettingsPanel * Add the 1.12.2 gui textures * First pass ItemSettings GUI * Item conduit&filter gui * Fix broken texture height on other panels * Improved fluid conduit gui * Make sure inventory slots are hidden by default on conduit guis * Clear ghost slots on tab changes * Update EnderCore version --- .editorconfig | 5 +- build.gradle | 180 +++++++- dependencies.gradle | 2 +- .../java/crazypants/enderio/CommonProxy.java | 10 +- .../enderio/conduit/BlockConduitBundle.java | 14 +- .../conduit/gui/BaseSettingsPanel.java | 319 ++++++++++--- .../gui/ExternalConnectionContainer.java | 45 +- .../enderio/conduit/gui/FakeButton.java | 72 +++ .../enderio/conduit/gui/FilterGuiUtil.java | 21 + .../conduit/gui/GuiExternalConnection.java | 83 +++- .../enderio/conduit/gui/LiquidSettings.java | 272 +++++------ .../conduit/gui/item/BasicItemFilterGui.java | 64 +-- .../conduit/gui/item/BigItemFilterGui.java | 35 +- .../gui/item/ExistingItemFilterGui.java | 132 +++--- .../conduit/gui/item/ItemSettings.java | 431 ++++++------------ .../conduit/gui/item/ModItemFilterGui.java | 62 ++- .../conduit/gui/item/PowerItemFilterGui.java | 30 +- .../item/filter/ExistingItemFilter.java | 16 +- .../conduit/item/filter/IItemFilter.java | 4 + .../conduit/item/filter/ItemFilter.java | 7 +- .../conduit/item/filter/ItemFilterBig.java | 8 +- .../conduit/item/filter/ModItemFilter.java | 4 + .../conduit/item/filter/PowerItemFilter.java | 10 + .../machine/transceiver/gui/FilterTab.java | 4 +- .../resources/assets/enderio/lang/en_US.lang | 77 ++++ .../textures/gui/23/advanced_item_filter.png | Bin 0 -> 1722 bytes .../textures/gui/23/basic_item_filter.png | Bin 0 -> 1923 bytes .../textures/gui/23/big_item_filter.png | Bin 0 -> 1937 bytes .../textures/gui/23/filter_settings.png | Bin 0 -> 1961 bytes .../gui/23/filter_upgrade_settings.png | Bin 0 -> 10612 bytes .../enderio/textures/gui/23/fluid_filter.png | Bin 0 -> 1923 bytes .../textures/gui/23/in_out_settings.png | Bin 0 -> 10069 bytes .../enderio/textures/gui/23/item_filter.png | Bin 0 -> 1883 bytes .../textures/gui/23/mod_item_filter.png | Bin 0 -> 1975 bytes .../textures/gui/23/simple_settings.png | Bin 0 -> 1132 bytes .../textures/gui/23/soul_filter_big.png | Bin 0 -> 1794 bytes .../textures/gui/23/soul_filter_normal.png | Bin 0 -> 1690 bytes .../textures/gui/23/upgrade_settings.png | Bin 0 -> 1935 bytes .../enderio/textures/gui/23/widgetsv2.png | Bin 0 -> 39317 bytes 39 files changed, 1192 insertions(+), 715 deletions(-) create mode 100644 src/main/java/crazypants/enderio/conduit/gui/FakeButton.java create mode 100644 src/main/java/crazypants/enderio/conduit/gui/FilterGuiUtil.java create mode 100644 src/main/resources/assets/enderio/textures/gui/23/advanced_item_filter.png create mode 100644 src/main/resources/assets/enderio/textures/gui/23/basic_item_filter.png create mode 100644 src/main/resources/assets/enderio/textures/gui/23/big_item_filter.png create mode 100644 src/main/resources/assets/enderio/textures/gui/23/filter_settings.png create mode 100644 src/main/resources/assets/enderio/textures/gui/23/filter_upgrade_settings.png create mode 100644 src/main/resources/assets/enderio/textures/gui/23/fluid_filter.png create mode 100644 src/main/resources/assets/enderio/textures/gui/23/in_out_settings.png create mode 100644 src/main/resources/assets/enderio/textures/gui/23/item_filter.png create mode 100644 src/main/resources/assets/enderio/textures/gui/23/mod_item_filter.png create mode 100644 src/main/resources/assets/enderio/textures/gui/23/simple_settings.png create mode 100644 src/main/resources/assets/enderio/textures/gui/23/soul_filter_big.png create mode 100644 src/main/resources/assets/enderio/textures/gui/23/soul_filter_normal.png create mode 100644 src/main/resources/assets/enderio/textures/gui/23/upgrade_settings.png create mode 100644 src/main/resources/assets/enderio/textures/gui/23/widgetsv2.png diff --git a/.editorconfig b/.editorconfig index 99d6c89454..13ec2b0f20 100644 --- a/.editorconfig +++ b/.editorconfig @@ -20,4 +20,7 @@ indent_size = 2 [*.java] indent_size = 2 -ij_java_space_before_if_parentheses = false \ No newline at end of file +ij_java_space_before_if_parentheses = false + +[*.lang] +trim_trailing_whitespace = false diff --git a/build.gradle b/build.gradle index c09bee22f3..515d16d467 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,4 @@ -//version: 1652851397 +//version: 1655755555 /* DO NOT CHANGE THIS FILE! @@ -12,7 +12,12 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import org.gradle.internal.logging.text.StyledTextOutput.Style import org.gradle.internal.logging.text.StyledTextOutputFactory +import java.nio.file.Files +import java.nio.file.Paths import java.util.concurrent.TimeUnit +import java.util.zip.ZipEntry +import java.util.zip.ZipInputStream +import java.util.zip.ZipOutputStream buildscript { repositories { @@ -105,6 +110,9 @@ checkPropertyExists("developmentEnvironmentUserName") boolean noPublishedSources = project.findProperty("noPublishedSources") ? project.noPublishedSources.toBoolean() : false boolean usesMixinDebug = project.findProperty('usesMixinDebug') ?: project.usesMixins.toBoolean() +String channel = project.findProperty('channel') ? project.channel : 'stable' +String mappingsVersion = project.findProperty('mappingsVersion') ? project.mappingsVersion : '12' +String remoteMappings = project.findProperty('remoteMappings') ? project.remoteMappings : 'https://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/conf/' String javaSourceDir = "src/main/java/" String scalaSourceDir = "src/main/scala/" @@ -669,7 +677,103 @@ configure(updateBuildScript) { description = 'Updates the build script to the latest version' } -// Deobfuscation +// Parameter Deobfuscation + +task deobfParams { + doLast { + + String mcpDir = "$project.gradle.gradleUserHomeDir/caches/minecraft/de/oceanlabs/mcp/mcp_$channel/$mappingsVersion" + String mcpZIP = "$mcpDir/mcp_$channel-$mappingsVersion-${minecraftVersion}.zip" + String paramsCSV = "$mcpDir/params.csv" + + download.run { + src "https://maven.minecraftforge.net/de/oceanlabs/mcp/mcp_$channel/$mappingsVersion-$minecraftVersion/mcp_$channel-$mappingsVersion-${minecraftVersion}.zip" + dest mcpZIP + overwrite false + } + + if(!file(paramsCSV).exists()) { + println("Extracting MCP archive ...") + unzip(mcpZIP, mcpDir) + } + + println("Parsing params.csv ...") + Map params = new HashMap<>() + Files.lines(Paths.get(paramsCSV)).forEach{line -> + String[] cells = line.split(",") + if(cells.length > 2 && cells[0].matches("p_i?\\d+_\\d+_")) { + params.put(cells[0], cells[1]) + } + } + + out.style(Style.Success).println("Modified ${replaceParams(file("$projectDir/src/main/java"), params)} files!") + out.style(Style.Failure).println("Don't forget to verify that the code still works as before!\n It could be broken due to duplicate variables existing now\n or parameters taking priority over other variables.") + } +} + +static int replaceParams(File file, Map params) { + int fileCount = 0 + + if(file.isDirectory()) { + for(File f : file.listFiles()) { + fileCount += replaceParams(f, params) + } + return fileCount + } + println("Visiting ${file.getName()} ...") + try { + String content = new String(Files.readAllBytes(file.toPath())) + int hash = content.hashCode() + params.forEach{key, value -> + content = content.replaceAll(key, value) + } + if(hash != content.hashCode()) { + Files.write(file.toPath(), content.getBytes("UTF-8")) + return 1 + } + } catch(Exception e) { + e.printStackTrace() + } + return 0 +} + +// Credit: bitsnaps (https://gist.github.com/bitsnaps/00947f2dce66f4bbdabc67d7e7b33681) +static unzip(String zipFileName, String outputDir) { + byte[] buffer = new byte[16384] + ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFileName)) + ZipEntry zipEntry = zis.getNextEntry() + while (zipEntry != null) { + File newFile = new File(outputDir + File.separator, zipEntry.name) + if (zipEntry.isDirectory()) { + if (!newFile.isDirectory() && !newFile.mkdirs()) { + throw new IOException("Failed to create directory $newFile") + } + } else { + // fix for Windows-created archives + File parent = newFile.parentFile + if (!parent.isDirectory() && !parent.mkdirs()) { + throw new IOException("Failed to create directory $parent") + } + // write file content + FileOutputStream fos = new FileOutputStream(newFile) + int len = 0 + while ((len = zis.read(buffer)) > 0) { + fos.write(buffer, 0, len) + } + fos.close() + } + zipEntry = zis.getNextEntry() + } + zis.closeEntry() + zis.close() +} + +configure(deobfParams) { + group = 'forgegradle' + description = 'Rename all obfuscated parameter names inherited from Minecraft classes' +} + +// Dependency Deobfuscation def deobf(String sourceURL) { try { @@ -682,7 +786,7 @@ def deobf(String sourceURL) { fileName = fileName.substring(lastSlash + 1) } //get rid of extension: - if(fileName.endsWith(".jar")) { + if(fileName.endsWith(".jar") || fileName.endsWith(".litemod")) { fileName = fileName.substring(0, fileName.lastIndexOf(".")) } @@ -694,26 +798,40 @@ def deobf(String sourceURL) { Collections.reverse(parts) hostName = String.join(".", parts) - return deobf(sourceURL, hostName + "/" + fileName) + return deobf(sourceURL, "$hostName/$fileName") } catch(Exception e) { - return deobf(sourceURL, "deobf/" + String.valueOf(sourceURL.hashCode())) + return deobf(sourceURL, "deobf/${sourceURL.hashCode()}") } } // The method above is to be preferred. Use this method if the filename is not at the end of the URL. -def deobf(String sourceURL, String fileName) { - String cacheDir = System.getProperty("user.home") + "/.gradle/caches/" - String bon2Dir = cacheDir + "forge_gradle/deobf" - String bon2File = bon2Dir + "/BON2-2.5.0.jar" - String obfFile = cacheDir + "modules-2/files-2.1/" + fileName + ".jar" - String deobfFile = cacheDir + "modules-2/files-2.1/" + fileName + "-deobf.jar" +def deobf(String sourceURL, String rawFileName) { + String bon2Version = "2.5.1" + String fileName = URLDecoder.decode(rawFileName, "UTF-8") + String cacheDir = "$project.gradle.gradleUserHomeDir/caches" + String bon2Dir = "$cacheDir/forge_gradle/deobf" + String bon2File = "$bon2Dir/BON2-${bon2Version}.jar" + String obfFile = "$cacheDir/modules-2/files-2.1/${fileName}.jar" + String deobfFile = "$cacheDir/modules-2/files-2.1/${fileName}-deobf.jar" if(file(deobfFile).exists()) { return files(deobfFile) } + String mappingsVer + if(remoteMappings) { + String id = "${forgeVersion.split("\\.")[3]}-$minecraftVersion" + String mappingsZIP = "$cacheDir/forge_gradle/maven_downloader/de/oceanlabs/mcp/mcp_snapshot_nodoc/$id/mcp_snapshot_nodoc-${id}.zip" + + zipMappings(mappingsZIP, remoteMappings, bon2Dir) + + mappingsVer = "snapshot_$id" + } else { + mappingsVer = "${channel}_$mappingsVersion" + } + download.run { - src 'https://github.com/GTNewHorizons/BON2/releases/download/2.5.0/BON2-2.5.0.CUSTOM-all.jar' + src "http://jenkins.usrv.eu:8081/nexus/content/repositories/releases/com/github/parker8283/BON2/$bon2Version-CUSTOM/BON2-$bon2Version-CUSTOM-all.jar" dest bon2File quiet true overwrite false @@ -727,14 +845,48 @@ def deobf(String sourceURL, String fileName) { } exec { - commandLine 'java', '-jar', bon2File, '--inputJar', obfFile, '--outputJar', deobfFile, '--mcVer', '1.7.10', '--mappingsVer', 'stable_12', '--notch' + commandLine 'java', '-jar', bon2File, '--inputJar', obfFile, '--outputJar', deobfFile, '--mcVer', minecraftVersion, '--mappingsVer', mappingsVer, '--notch' workingDir bon2Dir - standardOutput = new ByteArrayOutputStream() + standardOutput = new FileOutputStream("${deobfFile}.log") } return files(deobfFile) } +def zipMappings(String zipPath, String url, String bon2Dir) { + File zipFile = new File(zipPath) + if(zipFile.exists()) { + return + } + + String fieldsCache = "$bon2Dir/data/fields.csv" + String methodsCache = "$bon2Dir/data/methods.csv" + + download.run { + src "${url}fields.csv" + dest fieldsCache + quiet true + } + download.run { + src "${url}methods.csv" + dest methodsCache + quiet true + } + + zipFile.getParentFile().mkdirs() + ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile)) + + zos.putNextEntry(new ZipEntry("fields.csv")) + Files.copy(Paths.get(fieldsCache), zos) + zos.closeEntry() + + zos.putNextEntry(new ZipEntry("methods.csv")) + Files.copy(Paths.get(methodsCache), zos) + zos.closeEntry() + + zos.close() +} + // Helper methods def checkPropertyExists(String propertyName) { diff --git a/dependencies.gradle b/dependencies.gradle index 764b952e1e..012c17d24c 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -1,7 +1,7 @@ // Add your dependencies here dependencies { - compile('com.github.GTNewHorizons:EnderCore:0.2.6:dev') + compile('com.github.GTNewHorizons:EnderCore:0.2.9:dev') compile('com.github.GTNewHorizons:ForestryMC:4.4.6:dev') compile('com.github.GTNewHorizons:NotEnoughItems:2.2.15-GTNH:dev') compile('com.github.GTNewHorizons:BuildCraft:7.1.27:dev') diff --git a/src/main/java/crazypants/enderio/CommonProxy.java b/src/main/java/crazypants/enderio/CommonProxy.java index f8c35693cb..6ff26a2f2d 100644 --- a/src/main/java/crazypants/enderio/CommonProxy.java +++ b/src/main/java/crazypants/enderio/CommonProxy.java @@ -5,6 +5,7 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; +import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.eventhandler.SubscribeEvent; @@ -44,7 +45,7 @@ public double getReachDistanceForPlayer(EntityPlayer entityPlayer) { public void loadIcons() { ; } - + public void load() { FMLCommonHandler.instance().bus().register(tickTimer); } @@ -68,6 +69,13 @@ protected void onServerTick() { protected void onClientTick() { } + private static final String TEXTURE_PATH = ":textures/gui/23/"; + private static final String TEXTURE_EXT = ".png"; + + public ResourceLocation getGuiTexture(String name) { + return new ResourceLocation(EnderIO.DOMAIN + TEXTURE_PATH + name + TEXTURE_EXT); + } + public final class TickTimer { @SubscribeEvent diff --git a/src/main/java/crazypants/enderio/conduit/BlockConduitBundle.java b/src/main/java/crazypants/enderio/conduit/BlockConduitBundle.java index c34be729e1..e1d8cf9bbe 100644 --- a/src/main/java/crazypants/enderio/conduit/BlockConduitBundle.java +++ b/src/main/java/crazypants/enderio/conduit/BlockConduitBundle.java @@ -142,7 +142,7 @@ public boolean addHitEffects(World world, MovingObjectPosition target, EffectRen if (MicroblocksUtil.supportMicroblocks() && IM__addHitEffects(world, target, effectRenderer)) { return true; } - + IIcon tex = null; TileConduitBundle cb = (TileConduitBundle) world.getTileEntity(target.blockX, target.blockY, target.blockZ); @@ -263,7 +263,7 @@ protected void init() { public ItemStack getPickBlock(MovingObjectPosition target, World world, int x, int y, int z) { return getPickBlock(target, world, x, y, z, null); } - + @Override public ItemStack getPickBlock(MovingObjectPosition target, World world, int x, int y, int z, EntityPlayer player) { ItemStack ret = null; @@ -532,7 +532,7 @@ private boolean breakConduit(IConduitBundle te, List drop, RaytraceRe drop.addAll(con.getDrops()); } } - + BlockCoord bc = te.getLocation(); ConduitUtil.playBreakSound(Block.soundTypeMetal, te.getWorld(), bc.x, bc.y, bc.z); @@ -699,7 +699,7 @@ public boolean handleFacadeClick(World world, int x, int y, int z, EntityPlayer if (MicroblocksUtil.supportMicroblocks() && hasMicroblocks(bundle)) { return false; } - + // Add facade if(player.isSneaking()) { return false; @@ -724,7 +724,7 @@ public boolean handleFacadeClick(World world, int x, int y, int z, EntityPlayer Util.dropItems(world, fac, x, y, z, false); } } - + bundle.setFacadeId(facadeID); bundle.setFacadeMetadata(facadeMeta); bundle.setFacadeType(FacadeType.values()[facadeType]); @@ -817,7 +817,7 @@ public void onNeighborChange(IBlockAccess world, int x, int y, int z, int tileX, @Override public void addCollisionBoxesToList(World world, int x, int y, int z, AxisAlignedBB axisalignedbb, @SuppressWarnings("rawtypes") List arraylist, Entity par7Entity) { - + if (MicroblocksUtil.supportMicroblocks()) { IM__addCollisionBoxesToList(world, x, y, z, axisalignedbb, arraylist, par7Entity); } @@ -1097,7 +1097,7 @@ private static IRedstoneConduit getRedstoneConduit(IBlockAccess world, int x, in IConduitBundle bundle = (IConduitBundle) te; return bundle.getConduit(IRedstoneConduit.class); } - + public ItemStack getMicroblockPickBlock(MovingObjectPosition target, World world, int x, int y, int z, EntityPlayer player) { return IMultipartSystem.instance.hook_getPickBlock(target, world, x, y, z, player); } diff --git a/src/main/java/crazypants/enderio/conduit/gui/BaseSettingsPanel.java b/src/main/java/crazypants/enderio/conduit/gui/BaseSettingsPanel.java index 166ea1f7ab..077ae2aafc 100644 --- a/src/main/java/crazypants/enderio/conduit/gui/BaseSettingsPanel.java +++ b/src/main/java/crazypants/enderio/conduit/gui/BaseSettingsPanel.java @@ -1,16 +1,24 @@ package crazypants.enderio.conduit.gui; -import java.awt.Color; - +import java.awt.*; +import java.util.ArrayList; +import java.util.List; + +import com.enderio.core.client.gui.button.CheckBox; +import com.enderio.core.client.gui.button.IconButton; +import com.enderio.core.client.gui.widget.GuiToolTip; +import com.enderio.core.client.handlers.SpecialTooltipHandler; +import crazypants.enderio.conduit.item.FunctionUpgrade; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.GuiButton; -import org.lwjgl.opengl.GL11; +import net.minecraft.util.ResourceLocation; + +import javax.annotation.Nonnull; import com.enderio.core.api.client.gui.ITabPanel; import com.enderio.core.api.client.render.IWidgetIcon; -import com.enderio.core.client.gui.button.MultiIconButton; import com.enderio.core.client.render.ColorUtil; import crazypants.enderio.EnderIO; @@ -20,76 +28,206 @@ import crazypants.enderio.gui.IconEIO; import crazypants.enderio.network.PacketHandler; + public class BaseSettingsPanel implements ITabPanel { - static final int PREV_MODE_B = 327; - static final int NEXT_MODE_B = 328; + static final int ID_INSERT_ENABLED = 327; + static final int ID_EXTRACT_ENABLED = 328; + protected static final int ID_INSERT_FILTER_OPTIONS = 329; + protected static final int ID_EXTRACT_FILTER_OPTIONS = 330; + protected final int ID_ENABLED = 331; + + protected final @Nonnull IWidgetIcon icon; + protected final @Nonnull GuiExternalConnection gui; + protected @Nonnull IConduit con; + protected final @Nonnull String typeName; + protected final @Nonnull ResourceLocation texture; + + protected ConnectionMode oldConnectionMode; - protected final IconEIO icon; - protected final GuiExternalConnection gui; - protected final IConduit con; - protected final String typeName; + private @Nonnull String inputHeading; + private @Nonnull String outputHeading; - protected MultiIconButton leftArrow; - protected MultiIconButton rightArrow; - protected String modeLabel; + private boolean insertEnabled = false; + private boolean extractEnabled = false; + + private boolean enabled = false; + + private final @Nonnull CheckBox extractEnabledB; + private final @Nonnull CheckBox insertEnabledB; + + private final @Nonnull CheckBox enabledB; protected int left = 0; protected int top = 0; protected int width = 0; protected int height = 0; + protected int rightColumn = 112; + protected int leftColumn = 22; protected int gap = 5; protected int customTop = 0; - protected BaseSettingsPanel(IconEIO icon, String typeName, GuiExternalConnection gui, IConduit con) { + protected int textureHeight = 166 + 29; + + private final @Nonnull GuiToolTip speedUpgradeTooltip; + private final @Nonnull GuiToolTip functionUpgradeTooltip; + protected @Nonnull GuiToolTip filterExtractUpgradeTooltip; + protected @Nonnull GuiToolTip filterInsertUpgradeTooltip; + + protected BaseSettingsPanel(@Nonnull IWidgetIcon icon, @Nonnull String typeName, @Nonnull GuiExternalConnection gui, @Nonnull IConduit con) { + this(icon, typeName, gui, con, "externalConduitConnection"); + } + + protected BaseSettingsPanel(@Nonnull IWidgetIcon icon, @Nonnull String typeName, @Nonnull GuiExternalConnection gui, @Nonnull IConduit con, + @Nonnull String texture) { this.icon = icon; this.typeName = typeName; this.gui = gui; this.con = con; + this.texture = EnderIO.proxy.getGuiTexture(texture); - modeLabel = EnderIO.lang.localize("gui.conduit.ioMode"); + inputHeading = getInputHeading(); + outputHeading = getOutputHeading(); FontRenderer fr = Minecraft.getMinecraft().fontRenderer; - int x = gap * 3 + fr.getStringWidth(modeLabel); - int y = 8;// + fr.FONT_HEIGHT; - - leftArrow = MultiIconButton.createLeftArrowButton(gui, PREV_MODE_B, x, y); - - x += leftArrow.getWidth() + gap + getLongestModeStringWidth() + gap; - rightArrow = MultiIconButton.createRightArrowButton(gui, NEXT_MODE_B, x, y); customTop = top + gap * 5 + fr.FONT_HEIGHT * 2; customTop -= 16; - //customTop = top; + + int x = leftColumn; + int y = 6; + + insertEnabledB = new CheckBox(gui, ID_INSERT_ENABLED, x, y); + + enabledB = new CheckBox(gui, ID_ENABLED, x, y); + + x = rightColumn; + + extractEnabledB = new CheckBox(gui, ID_EXTRACT_ENABLED, x, y); + + x = leftColumn; + y = 92; + + x = rightColumn; + + x = rightColumn + 18 + 1; + + filterExtractUpgradeTooltip = new GuiToolTip(new Rectangle(rightColumn, 70, 18, 18), EnderIO.lang.localize("gui.conduit.item.filterupgrade")) { + @Override + public boolean shouldDraw() { + return !gui.getContainer().hasFilterUpgrades(false) && super.shouldDraw(); + } + }; + + filterInsertUpgradeTooltip = new GuiToolTip(new Rectangle(leftColumn, 70, 18, 18), EnderIO.lang.localize("gui.conduit.item.filterupgrade")) { + @Override + public boolean shouldDraw() { + return !gui.getContainer().hasFilterUpgrades(true) && super.shouldDraw(); + } + }; + + speedUpgradeTooltip = new GuiToolTip(new Rectangle(rightColumn + 18, customTop + 43, 18, 18), EnderIO.lang.localize("gui.conduit.item.speedupgrade"), + EnderIO.lang.localize("gui.conduit.item.speedupgrade2")) { + @Override + public boolean shouldDraw() { + return !gui.getContainer().hasSpeedUpgrades() && super.shouldDraw(); + } + }; + + ArrayList funcUpgradeTips = new ArrayList(); + SpecialTooltipHandler.addTooltipFromResources(funcUpgradeTips, "enderio.gui.conduit.item.functionupgrade.line"); + for(FunctionUpgrade upgrade : FunctionUpgrade.values()) { + funcUpgradeTips.add(EnderIO.lang.localizeExact(upgrade.unlocName.concat(".name"))); + } + functionUpgradeTooltip = new GuiToolTip(new Rectangle(rightColumn + 36, customTop + 43, 18, 18), funcUpgradeTips.toArray(new String[0])) { + @Override + public boolean shouldDraw() { + return !gui.getContainer().hasFunctionUpgrades() && super.shouldDraw(); + } + }; + + gui.getContainer().setInoutSlotsVisible(false, false); } @Override - public void onGuiInit(int left, int top, int width, int height) { - this.left = left; - this.top = top; - this.width = width; - this.height = height; + public ResourceLocation getTexture() { + return texture; + } + + public int getTextureHeight() { + return textureHeight; + } + + protected void updateFilterButtons() { + } + + protected boolean hasFilterGui(boolean input) { + return true; + } - leftArrow.onGuiInit(); - rightArrow.onGuiInit(); + public boolean updateConduit(@Nonnull IConduit conduit) { + this.con = conduit; + if (oldConnectionMode != con.getConnectionMode(gui.getDir())) { + connectionModeChanged(con.getConnectionMode(gui.getDir())); + } + return true; + } + + @Override + public void onGuiInit(int leftIn, int topIn, int widthIn, int heightIn) { + this.left = leftIn; + this.top = topIn; + this.width = widthIn; + this.height = heightIn; + + updateConduit(con); + + if (hasInOutModes()) { + insertEnabledB.onGuiInit(); + extractEnabledB.onGuiInit(); + + insertEnabledB.setSelected(insertEnabled); + extractEnabledB.setSelected(extractEnabled); + } else { + enabledB.onGuiInit(); + enabledB.setSelected(enabled); + } - connectionModeChanged(con.getConnectionMode(gui.getDir())); + if (hasFilters()) { + gui.addToolTip(filterExtractUpgradeTooltip); + gui.addToolTip(filterInsertUpgradeTooltip); + } + if (hasUpgrades()) { + gui.addToolTip(speedUpgradeTooltip); + gui.addToolTip(functionUpgradeTooltip); + } initCustomOptions(); } + protected boolean hasUpgrades() { + return false; + } + protected void initCustomOptions() { } @Override public void deactivate() { + insertEnabledB.detach(); + extractEnabledB.detach(); + + gui.removeToolTip(speedUpgradeTooltip); + gui.removeToolTip(functionUpgradeTooltip); + gui.removeToolTip(filterExtractUpgradeTooltip); + gui.removeToolTip(filterInsertUpgradeTooltip); } - + @Override - public void mouseClicked(int x, int y, int par3) { + public void mouseClicked(int x, int y, int par3) { } @Override @@ -97,79 +235,108 @@ public void keyTyped(char par1, int par2) { } @Override - public void updateScreen() { + public void updateScreen() { } @Override + @Nonnull public IWidgetIcon getIcon() { return icon; } - @Override - public void actionPerformed(GuiButton guiButton) { - if(guiButton.id == PREV_MODE_B) { - con.setConnectionMode(gui.getDir(), con.getPreviousConnectionMode(gui.getDir())); - PacketHandler.INSTANCE.sendToServer(new PacketConnectionMode(con, gui.getDir())); - connectionModeChanged(con.getConnectionMode(gui.getDir())); + private void updateConnectionMode() { + ConnectionMode mode = ConnectionMode.DISABLED; + if (insertEnabled && extractEnabled || enabled) { + mode = ConnectionMode.IN_OUT; + } else if (insertEnabled) { + mode = ConnectionMode.OUTPUT; + } else if (extractEnabled) { + mode = ConnectionMode.INPUT; + } + con.setConnectionMode(gui.getDir(), mode); + PacketHandler.INSTANCE.sendToServer(new PacketConnectionMode(con, gui.getDir())); + } - } else if(guiButton.id == NEXT_MODE_B) { - con.setConnectionMode(gui.getDir(), con.getNextConnectionMode(gui.getDir())); - PacketHandler.INSTANCE.sendToServer(new PacketConnectionMode(con, gui.getDir())); - connectionModeChanged(con.getConnectionMode(gui.getDir())); + @Override + public void actionPerformed(@Nonnull GuiButton guiButton) { + if (guiButton.id == ID_INSERT_ENABLED) { + insertEnabled = !insertEnabled; + updateConnectionMode(); + } else if (guiButton.id == ID_EXTRACT_ENABLED) { + extractEnabled = !extractEnabled; + updateConnectionMode(); + } else if (guiButton.id == ID_ENABLED) { + enabled = !enabled; + updateConnectionMode(); } } - protected void connectionModeChanged(ConnectionMode conectionMode) { + protected void connectionModeChanged(@Nonnull ConnectionMode mode) { + oldConnectionMode = mode; + if (hasInOutModes()) { + insertEnabled = mode.acceptsOutput(); + extractEnabled = mode.acceptsInput(); + } else { + enabled = mode == ConnectionMode.IN_OUT; + } } @Override public void render(float par1, int par2, int par3) { + updateFilterButtons(); + FontRenderer fr = gui.getFontRenderer(); int rgb = ColorUtil.getRGB(Color.darkGray); - int x = left + (width - fr.getStringWidth(getTypeName())) / 2; - - //fr.drawString(getTypeName(), x, top, rgb); + int x = left + 32; + int y = gui.getGuiTop() + 10; + + if (hasInOutModes()) { + fr.drawString(inputHeading, x, y, rgb); + x += 92; + fr.drawString(outputHeading, x, y, rgb); + } else { + String heading = enabled ? getEnabledHeading() : getDisabledHeading(); + fr.drawString(heading, x, y, rgb); + } + renderCustomOptions(y + gap + fr.FONT_HEIGHT + gap, par1, par2, par3); + } - x = left; - - int y = gui.getGuiTop() + 13;//customTop + 8;//gap + fr.FONT_HEIGHT + gap; - gui.getFontRenderer().drawString(modeLabel, x, y, rgb); + protected void renderCustomOptions(int topIn, float par1, int par2, int par3) { - String modeString = con.getConnectionMode(gui.getDir()).getLocalisedName(); - x += gap + leftArrow.getWidth() + fr.getStringWidth(modeLabel) + gap; + } - GL11.glColor3f(1, 1, 1); - // TODO figure out what this should be -// IconEIO icon = new IconEIO(10, 48, 64, 16); -// icon.getMap().render(icon, x - gap, y - (fr.FONT_HEIGHT / 2) - 1, getLongestModeStringWidth() + gap * 2, leftArrow.getHeight(), 0, true); + protected @Nonnull String getTypeName() { + return typeName; + } - int move = (getLongestModeStringWidth() - fr.getStringWidth(modeString)) / 2; - x += move; - rgb = ColorUtil.getRGB(Color.white); - gui.getFontRenderer().drawString(modeString, x, y, rgb); + protected boolean hasFilters() { + return false; + } - renderCustomOptions(y + gap + fr.FONT_HEIGHT + gap, par1, par2, par3); - //renderCustomOptions(y + gap, par1, par2, par3); + @Nonnull + protected String getInputHeading() { + // lang strings are nonintuitive for some reason + return EnderIO.lang.localize("gui.conduit.ioMode.output"); } - protected void renderCustomOptions(int top, float par1, int par2, int par3) { + @Nonnull + protected String getOutputHeading() { + return EnderIO.lang.localize("gui.conduit.ioMode.input"); + } + @Nonnull + protected String getEnabledHeading() { + return EnderIO.lang.localize("gui.enabled"); } - private int getLongestModeStringWidth() { - int maxWidth = 0; - for (ConnectionMode mode : ConnectionMode.values()) { - int width = gui.getFontRenderer().getStringWidth(mode.getLocalisedName()); - if(width > maxWidth) { - maxWidth = width; - } - } - return maxWidth; + @Nonnull + protected String getDisabledHeading() { + return EnderIO.lang.localize("gui.disabled"); } - protected String getTypeName() { - return typeName; + protected boolean hasInOutModes() { + return true; } } diff --git a/src/main/java/crazypants/enderio/conduit/gui/ExternalConnectionContainer.java b/src/main/java/crazypants/enderio/conduit/gui/ExternalConnectionContainer.java index f7556f12c9..8c2f44612c 100644 --- a/src/main/java/crazypants/enderio/conduit/gui/ExternalConnectionContainer.java +++ b/src/main/java/crazypants/enderio/conduit/gui/ExternalConnectionContainer.java @@ -2,8 +2,10 @@ import java.awt.Point; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import crazypants.enderio.conduit.item.filter.IItemFilter; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.IInventory; @@ -27,6 +29,7 @@ public class ExternalConnectionContainer extends ContainerEnder { private final IItemConduit itemConduit; + private final ForgeDirection direction; private int speedUpgradeSlotLimit = 15; @@ -40,13 +43,14 @@ public class ExternalConnectionContainer extends ContainerEnder slotLocations = new ArrayList(); + private final List slotLocations = new ArrayList<>(); - final List filterListeners = new ArrayList(); - final List bgSlots = new ArrayList(); + final List filterListeners = new ArrayList<>(); + final List bgSlots = new ArrayList<>(); public ExternalConnectionContainer(InventoryPlayer playerInv, IConduitBundle bundle, ForgeDirection dir) { super(playerInv, new InventoryUpgrades(bundle.getConduit(IItemConduit.class), dir)); + this.direction = dir; this.itemConduit = bundle.getConduit(IItemConduit.class); slotLocations.addAll(playerSlotLocations.values()); @@ -54,20 +58,20 @@ public ExternalConnectionContainer(InventoryPlayer playerInv, IConduitBundle bun int y; if (itemConduit != null) { - x = 10; - y = 47; + x = 113; + y = 71; slotOutputFilterUpgrades = addSlotToContainer(new FilterSlot(getInv(), 3, x, y)); slotLocations.add(new Point(x, y)); bgSlots.add(new GhostBackgroundItemSlot(EnderIO.itemBasicFilterUpgrade, slotOutputFilterUpgrades)); - x = 10; - y = 47; + x = 23; + y = 71; slotInputFilterUpgrades = addSlotToContainer(new FilterSlot(getInv(), 2, x, y)); slotLocations.add(new Point(x, y)); bgSlots.add(new GhostBackgroundItemSlot(EnderIO.itemBasicFilterUpgrade, slotInputFilterUpgrades)); - x = 10; - y = 83; + x = 131; + y = 71; slotSpeedUpgrades = addSlotToContainer(new Slot(getInv(), 0, x, y) { @Override public boolean isItemValid(ItemStack par1ItemStack) { @@ -82,8 +86,8 @@ public int getSlotStackLimit() { slotLocations.add(new Point(x, y)); bgSlots.add(new GhostBackgroundItemSlot(EnderIO.itemExtractSpeedUpgrade, slotSpeedUpgrades)); - x = 10; - y = 65; + x = 149; + y = 71; slotFunctionUpgrades = addSlotToContainer(new Slot(getInv(), 1, x, y) { @Override public boolean isItemValid(ItemStack par1ItemStack) { @@ -98,6 +102,8 @@ public int getSlotStackLimit() { slotLocations.add(new Point(x, y)); bgSlots.add(new GhostBackgroundItemSlot(EnderIO.itemFunctionUpgrade, slotFunctionUpgrades)); } + + setInventorySlotsVisible(false); } public void createGhostSlots(List slots) { @@ -106,7 +112,7 @@ public void createGhostSlots(List slots) { @Override public Point getPlayerInventoryOffset() { - return new Point(23, 113); + return new Point(23, 161); } public void addFilterListener(FilterChangeListener list) { @@ -132,6 +138,17 @@ public boolean hasFilterUpgrades(boolean input) { return slot != null && slot.getHasStack(); } + public ForgeDirection getDirection() { + return direction; + } + + public IItemFilter getFilter(boolean input) { + if (itemConduit == null) { + return null; + } + return input ? itemConduit.getInputFilter(direction) : itemConduit.getOutputFilter(direction); + } + public void setInoutSlotsVisible(boolean inputVisible, boolean outputVisible) { if(itemConduit == null) { return; @@ -282,4 +299,8 @@ public boolean isItemValid(ItemStack par1ItemStack) { } + public List getFunctionUpgradeToolTipText() { + return Collections.emptyList(); + } + } diff --git a/src/main/java/crazypants/enderio/conduit/gui/FakeButton.java b/src/main/java/crazypants/enderio/conduit/gui/FakeButton.java new file mode 100644 index 0000000000..d961d84d08 --- /dev/null +++ b/src/main/java/crazypants/enderio/conduit/gui/FakeButton.java @@ -0,0 +1,72 @@ +package crazypants.enderio.conduit.gui; + +import javax.annotation.Nonnull; + +import com.enderio.core.client.gui.button.TooltipButton; +import org.lwjgl.opengl.GL11; + +import com.enderio.core.api.client.gui.IGuiScreen; +import com.enderio.core.api.client.render.IWidgetIcon; + +import net.minecraft.client.Minecraft; + +public class FakeButton extends TooltipButton { + + public static final int DEFAULT_WIDTH = 16; + public static final int DEFAULT_HEIGHT = 16; + + protected @Nonnull IWidgetIcon icon; + + private int marginY = 0; + private int marginX = 0; + + public FakeButton(@Nonnull IGuiScreen gui, int x, int y, @Nonnull IWidgetIcon icon) { + super(gui, -1, x, y, DEFAULT_WIDTH, DEFAULT_HEIGHT, ""); + this.icon = icon; + } + + @Override + public FakeButton setPosition(int x, int y) { + super.setPosition(x, y); + return this; + } + + public FakeButton setIconMargin(int x, int y) { + marginX = x; + marginY = y; + return this; + } + + public @Nonnull IWidgetIcon getIcon() { + return icon; + } + + public void setIcon(@Nonnull IWidgetIcon icon) { + this.icon = icon; + } + + public boolean mousePressedButton(@Nonnull Minecraft mc, int mouseX, int mouseY, int button) { + return false; + } + + protected boolean checkMousePress(@Nonnull Minecraft mc, int mouseX, int mouseY) { + return false; + } + + /** + * Draws this button to the screen. + */ + @Override + public void drawButton(@Nonnull Minecraft mc, int mouseX, int mouseY) { + updateTooltip(mc, mouseX, mouseY); + if (isVisible()) { + GL11.glPushAttrib(GL11.GL_ENABLE_BIT); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + icon.getMap().render(icon, xPosition + marginX, yPosition + marginY, width - 2 * marginX, height - 2 * marginY, 0, true); + GL11.glPopAttrib(); + } + } + +} diff --git a/src/main/java/crazypants/enderio/conduit/gui/FilterGuiUtil.java b/src/main/java/crazypants/enderio/conduit/gui/FilterGuiUtil.java new file mode 100644 index 0000000000..8c8995c240 --- /dev/null +++ b/src/main/java/crazypants/enderio/conduit/gui/FilterGuiUtil.java @@ -0,0 +1,21 @@ +package crazypants.enderio.conduit.gui; + +public class FilterGuiUtil { + + // List of filter indexes for reference in guis + public static final int INDEX_INPUT_ITEM = 1; + public static final int INDEX_OUTPUT_ITEM = 2; + public static final int INDEX_INPUT_FLUID = 3; + public static final int INDEX_OUTPUT_FLUID = 4; + public static final int INDEX_INPUT_REDSTONE = 6; + public static final int INDEX_OUTPUT_REDSTONE = 5; + public static final int INDEX_NONE = 0; + + public static final int INDEX_FILTER_HANDHELD = -1; + + private static int nextButtonId = 1; + + public static int nextButtonId() { + return nextButtonId++; + } +} diff --git a/src/main/java/crazypants/enderio/conduit/gui/GuiExternalConnection.java b/src/main/java/crazypants/enderio/conduit/gui/GuiExternalConnection.java index af09ab0e56..98d1460342 100644 --- a/src/main/java/crazypants/enderio/conduit/gui/GuiExternalConnection.java +++ b/src/main/java/crazypants/enderio/conduit/gui/GuiExternalConnection.java @@ -7,6 +7,8 @@ import java.util.List; import java.util.Map; +import com.enderio.core.client.gui.GuiContainerBase; +import com.enderio.core.client.gui.widget.GhostSlot; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.Tessellator; @@ -43,6 +45,12 @@ public static int nextButtonId() { return nextButtonId++; } + public static int nextButtonIds(int count) { + int id = nextButtonId; + nextButtonId += count; + return id; + } + private static final Map, Integer> TAB_ORDER = new HashMap, Integer>(); static { TAB_ORDER.put(IItemConduit.class, 0); @@ -73,11 +81,10 @@ public GuiExternalConnection(InventoryPlayer playerInv, IConduitBundle bundle, F this.bundle = bundle; this.dir = dir; - ySize = 166 + 29; + ySize = 166 + 29 + 48; xSize = 206; container.setInoutSlotsVisible(false, false); - container.setInventorySlotsVisible(false); List cons = new ArrayList(bundle.getConduits()); Collections.sort(cons, new Comparator() { @@ -92,8 +99,7 @@ public int compare(IConduit o1, IConduit o2) { if(int2 == null) { return 1; } - //NB: using Double.comp instead of Integer.comp as the int version is only from Java 1.7+ - return Double.compare(int1, int2); + return Integer.compare(int1, int2); } }); @@ -105,12 +111,17 @@ public int compare(IConduit o1, IConduit o2) { if(tab != null) { conduits.add(con); tabs.add(tab); + tab.deactivate(); } } } } + public IConduitBundle getBundle() { + return bundle; + } + @Override public void initGui() { super.initGui(); @@ -119,8 +130,6 @@ public void initGui() { for (int i = 0; i < tabs.size(); i++) { if(i == activeTab) { tabs.get(i).onGuiInit(guiLeft + 10, guiTop, xSize - 20, ySize - 20); - } else { - tabs.get(i).deactivate(); } } } @@ -132,6 +141,16 @@ public boolean doesGuiPauseGame() { @Override protected void mouseClicked(int x, int y, int par3) { + // handle out-of-bounds ghost slots + boolean outOfBounds = x < guiLeft || y < guiTop || x >= guiLeft + xSize || y >= guiTop + ySize; + boolean hasItem = playerInv.getItemStack() != null; + if (outOfBounds && hasItem && !getGhostSlots().isEmpty()) { + GhostSlot slot = getGhostSlot(x, y); + if (slot != null) { + ghostSlotClicked(slot, x, y, par3); + return; + } + } super.mouseClicked(x, y, par3); int tabLeftX = xSize; @@ -145,6 +164,8 @@ protected void mouseClicked(int x, int y, int par3) { if(x > tabLeftX && x < tabRightX + 24) { if(y > minY && y < maxY) { + tabs.get(activeTab).deactivate(); + getGhostSlots().clear(); activeTab = (y - minY) / 24; initGui(); return; @@ -186,8 +207,17 @@ protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) { tes.draw(); - bindGuiTexture(); - drawTexturedModalRect(sx, sy, 0, 0, this.xSize, this.ySize); + int textureHeight = 166 + 29; + if (tabs.isEmpty()) { + bindGuiTexture(); + } else { + ITabPanel tab = tabs.get(activeTab); + RenderUtil.bindTexture(tab.getTexture()); + if (tab instanceof BaseSettingsPanel) { + textureHeight = ((BaseSettingsPanel) tab).getTextureHeight(); + } + } + drawTexturedModalRect(sx, sy, 0, 0, this.xSize, textureHeight); RenderUtil.bindTexture(IconEIO.TEXTURE); tes.startDrawingQuads(); @@ -216,13 +246,44 @@ public ExternalConnectionContainer getContainer() { @Override @Optional.Method(modid = "NotEnoughItems") public boolean hideItemPanelSlot(GuiContainer gc, int x, int y, int w, int h) { + int sx = (width - xSize) / 2; + int sy = (height - ySize) / 2; if(tabs.size() > 0) { - int sx = (width - xSize) / 2; - int sy = (height - ySize) / 2; int tabX = sx + xSize - 3; int tabY = sy + tabYOffset; - return (x+w) >= tabX && x < (tabX + 14) && (y+h) >= tabY && y < (tabY + tabs.size()*TAB_HEIGHT); + if((x+w) >= tabX && x < (tabX + 14) && (y+h) >= tabY && y < (tabY + tabs.size()*TAB_HEIGHT)) { + return true; + } + } + List slots = getGhostSlots(); + if (slots != null && !slots.isEmpty()) { + for (GhostSlot slot : slots) { + int slotX = sx + slot.x; + int slotY = sy + slot.y; + if((x+w) >= slotX && x < (slotX + 20) && (y+h) >= slotY && y < (slotY + 20)) { + return true; + } + } + } + return false; + } + + @Override + @Optional.Method(modid = "NotEnoughItems") + public boolean handleDragNDrop(GuiContainer gc, int x, int y, ItemStack is, int button) + { + if (super.handleDragNDrop(gc, x, y, is, button)) { + return true; + } + x -= guiLeft; + y -= guiTop; + if (is != null && is.stackSize > 0 && !tabs.isEmpty() && tabs.get(activeTab) instanceof LiquidSettings) { + LiquidSettings settings = (LiquidSettings) tabs.get(activeTab); + if (settings.setFilterFromItem(x, y, is)) { + is.stackSize = 0; + return true; + } } return false; } diff --git a/src/main/java/crazypants/enderio/conduit/gui/LiquidSettings.java b/src/main/java/crazypants/enderio/conduit/gui/LiquidSettings.java index 97aeeca6ee..b219d2dda6 100644 --- a/src/main/java/crazypants/enderio/conduit/gui/LiquidSettings.java +++ b/src/main/java/crazypants/enderio/conduit/gui/LiquidSettings.java @@ -44,16 +44,19 @@ public class LiquidSettings extends BaseSettingsPanel { private static final int ID_COLOR_BUTTON = GuiExternalConnection.nextButtonId(); private static final int ID_ROUND_ROBIN_BUTTON = GuiExternalConnection.nextButtonId(); - private static final int ID_WHITELIST = GuiExternalConnection.nextButtonId(); + private static final int ID_INSERT_WHITELIST = GuiExternalConnection.nextButtonId(); + private static final int ID_EXTRACT_WHITELIST = GuiExternalConnection.nextButtonId(); private static final int NEXT_FILTER_ID = 989322; - private static final int ID_CHANNEL = GuiExternalConnection.nextButtonId(); + private static final int ID_INSERT_CHANNEL = GuiExternalConnection.nextButtonId(); + private static final int ID_EXTRACT_CHANNEL = GuiExternalConnection.nextButtonId(); private final RedstoneModeButton rsB; private final ToggleButton roundRobinB; private final ColorButton colorB; - private ColorButton channelB; + private ColorButton insertChannelB; + private ColorButton extractChannelB; private static final String autoExtractStr = EnderIO.lang.localize("gui.conduit.fluid.autoExtract"); private static final String filterStr = EnderIO.lang.localize("gui.conduit.fluid.filter"); @@ -62,17 +65,20 @@ public class LiquidSettings extends BaseSettingsPanel { private AbstractEnderLiquidConduit eConduit; private boolean isEnder; - private static final int filterX = 59; + private static final int filterIX = 4; + private static final int filterEX = 104; private static final int filterY = 63; - private static final Rectangle filterBounds = new Rectangle(filterX, filterY, 90, 18); + private static final Rectangle insertFilterBounds = new Rectangle(filterIX, filterY, 90, 18); + private static final Rectangle extractFilterBounds = new Rectangle(filterEX, filterY, 90, 18); private GuiToolTip[] filterToolTips; private boolean inOutShowIn = true; - private MultiIconButton inOutNextB; - private IconButton whiteListB; + private IconButton insertWhiteListB; + private IconButton extractWhiteListB; protected LiquidSettings(final GuiExternalConnection gui, IConduit con) { - super(IconEIO.WRENCH_OVERLAY_FLUID, EnderIO.lang.localize("itemLiquidConduit.name"), gui, con); + super(IconEIO.WRENCH_OVERLAY_FLUID, EnderIO.lang.localize("itemLiquidConduit.name"), gui, con, "in_out_settings"); + this.textureHeight += 48; conduit = (ILiquidConduit) con; if(con instanceof AbstractEnderLiquidConduit) { @@ -80,33 +86,34 @@ protected LiquidSettings(final GuiExternalConnection gui, IConduit con) { isEnder = true; - int x = 52; + int x = leftColumn; int y = customTop; + insertWhiteListB = new IconButton(gui, ID_INSERT_WHITELIST, x, y, IconEIO.FILTER_WHITELIST); + insertWhiteListB.setToolTip(EnderIO.lang.localize("gui.conduit.fluid.whitelist")); - - inOutNextB = MultiIconButton.createRightArrowButton(gui, NEXT_FILTER_ID, x, y); - - x = filterX - 20; - y = filterY + 1; - - whiteListB = new IconButton(gui, ID_WHITELIST, x, y, IconEIO.FILTER_WHITELIST); - whiteListB.setToolTip(EnderIO.lang.localize("gui.conduit.fluid.whitelist")); + x = rightColumn; + extractWhiteListB = new IconButton(gui, ID_EXTRACT_WHITELIST, x, y, IconEIO.FILTER_WHITELIST); + extractWhiteListB.setToolTip(EnderIO.lang.localize("gui.conduit.fluid.whitelist")); } else { isEnder = false; gui.getContainer().setInventorySlotsVisible(false); } - int x = 66; + int x = leftColumn + 21; int y = customTop; if(isEnder) { - channelB = new ColorButton(gui, ID_CHANNEL, x, y); - channelB.setColorIndex(0); - channelB.setToolTipHeading(EnderIO.lang.localize("gui.conduit.item.channel")); - x += channelB.getWidth() + gap; + insertChannelB = new ColorButton(gui, ID_INSERT_CHANNEL, x, y); + insertChannelB.setColorIndex(0); + insertChannelB.setToolTipHeading(EnderIO.lang.localize("gui.conduit.item.channel")); + extractChannelB = new ColorButton(gui, ID_EXTRACT_CHANNEL, x + rightColumn - leftColumn, y); + extractChannelB.setColorIndex(0); + extractChannelB.setToolTipHeading(EnderIO.lang.localize("gui.conduit.item.channel")); + x += insertChannelB.getWidth(); } + x += rightColumn - leftColumn; rsB = new RedstoneModeButton(gui, ID_REDSTONE_BUTTON, x, y, new IRedstoneModeControlable() { @Override @@ -125,13 +132,13 @@ public RedstoneControlMode getRedstoneControlMode() { } }); - x += rsB.getWidth() + gap; + x += rsB.getWidth(); colorB = new ColorButton(gui, ID_COLOR_BUTTON, x, y); colorB.setToolTipHeading(EnderIO.lang.localize("gui.conduit.redstone.signalColor")); colorB.setColorIndex(conduit.getExtractionSignalColor(gui.getDir()).ordinal()); if (isEnder) { - x += rsB.getWidth() + gap; + x += rsB.getWidth(); roundRobinB = new ToggleButton(gui, ID_ROUND_ROBIN_BUTTON, x, y, IconEIO.ROUND_ROBIN_OFF, IconEIO.ROUND_ROBIN); roundRobinB.setSelectedToolTip(EnderIO.lang.localize("gui.conduit.item.roundRobinEnabled")); roundRobinB.setUnselectedToolTip(EnderIO.lang.localize("gui.conduit.item.roundRobinDisabled")); @@ -144,8 +151,13 @@ public RedstoneControlMode getRedstoneControlMode() { private void addFilterTooltips() { filterToolTips = new GuiToolTip[5]; for (int i = 0; i < 5; i++) { - Rectangle bound = new Rectangle(filterX + (i * 18), filterY, 18, 18); - filterToolTips[i] = new FilterToolTip(bound, i); + Rectangle bound = new Rectangle(filterIX + (i * 18), filterY, 18, 18); + filterToolTips[i] = new FilterToolTip(bound, i, false); + gui.addToolTip(filterToolTips[i]); + } + for (int i = 0; i < 5; i++) { + Rectangle bound = new Rectangle(filterEX + (i * 18), filterY, 18, 18); + filterToolTips[i] = new FilterToolTip(bound, i, true); gui.addToolTip(filterToolTips[i]); } } @@ -156,48 +168,24 @@ public void actionPerformed(GuiButton guiButton) { if(guiButton.id == ID_COLOR_BUTTON) { conduit.setExtractionSignalColor(gui.getDir(), DyeColor.values()[colorB.getColorIndex()]); PacketHandler.INSTANCE.sendToServer(new PacketExtractMode(conduit, gui.getDir())); - } else if(guiButton.id == ID_WHITELIST) { - toggleBlacklist(); - } else if(guiButton.id == NEXT_FILTER_ID) { - inOutShowIn = !inOutShowIn; - if(channelB != null) { - channelB.onGuiInit(); - if(isInput()) { - channelB.setColorIndex(eConduit.getInputColor(gui.getDir()).ordinal()); - } else { - channelB.setColorIndex(eConduit.getOutputColor(gui.getDir()).ordinal()); - } - } - if(isInput()) { - if (isEnder) { - roundRobinB.onGuiInit(); - } - rsB.onGuiInit(); - colorB.onGuiInit(); - } else { - if (isEnder) { - roundRobinB.detach(); - } - rsB.detach(); - colorB.detach(); - } - if(isFilterVisible()) { - updateWhiteListButton(eConduit.getFilter(gui.getDir(), isInput())); - } - } else if(guiButton.id == ID_CHANNEL) { + } else if(guiButton.id == ID_INSERT_WHITELIST || guiButton.id == ID_EXTRACT_WHITELIST) { + toggleBlacklist(guiButton.id == ID_EXTRACT_WHITELIST); + }else if(guiButton.id == ID_INSERT_CHANNEL || guiButton.id == ID_EXTRACT_CHANNEL) { + ColorButton btn = (ColorButton) guiButton; if(isEnder) { - DyeColor col = DyeColor.values()[channelB.getColorIndex()]; + DyeColor col = DyeColor.values()[btn.getColorIndex()]; + boolean isInput = guiButton.id == ID_EXTRACT_CHANNEL; - if (isInput()) { + if (isInput) { eConduit.setInputColor(gui.getDir(), col); } else { eConduit.setOutputColor(gui.getDir(), col); } - setConduitChannel(col); + setConduitChannel(isInput, col); } } else if(guiButton.id == ID_ROUND_ROBIN_BUTTON) { - if (isEnder && isInput()) { + if (isEnder) { final boolean selected = roundRobinB.isSelected(); eConduit.setRoundRobin(gui.getDir(), selected); PacketHandler.INSTANCE.sendToServer(new PacketRoundRobinMode(eConduit, gui.getDir())); @@ -211,17 +199,17 @@ protected void connectionModeChanged(ConnectionMode conectionMode) { updateGuiVisibility(); } - private void toggleBlacklist() { + private void toggleBlacklist(boolean isInput) { if(!isFilterVisible()) { return; } - FluidFilter filter = eConduit.getFilter(gui.getDir(), isInput()); + FluidFilter filter = eConduit.getFilter(gui.getDir(), isInput); if(filter == null) { filter = new FluidFilter(); } filter.setBlacklist(!filter.isBlacklist()); - setConduitFilter(filter); - updateWhiteListButton(filter); + setConduitFilter(isInput, filter); + updateWhiteListButton(filter, isInput); } @Override @@ -230,35 +218,56 @@ public void mouseClicked(int x, int y, int par3) { if(!isFilterVisible()) { return; } - if(!filterBounds.contains(x, y)) { - return; - } ItemStack st = Minecraft.getMinecraft().thePlayer.inventory.getItemStack(); - FluidFilter filter = eConduit.getFilter(gui.getDir(), isInput()); - if(filter == null && st == null) { + if (st == null && par3 == 0) { return; } - if(filter == null) { - filter = new FluidFilter(); + setFilterFromItem(x, y, st); + } + + public boolean setFilterFromItem(int x, int y, ItemStack st) { + if (insertFilterBounds.contains(x, y)) { + FluidFilter filter = eConduit.getFilter(gui.getDir(), false); + if(filter == null && st == null) { + return false; + } + if(filter == null) { + filter = new FluidFilter(); + } + int slot = (x - filterIX) / 18; + filter.setFluid(slot, st); + setConduitFilter(false, filter); + return true; } - int slot = (x - filterX) / 18; - filter.setFluid(slot, st); - setConduitFilter(filter); + if (extractFilterBounds.contains(x, y)) { + FluidFilter filter = eConduit.getFilter(gui.getDir(), true); + if(filter == null && st == null) { + return false; + } + if(filter == null) { + filter = new FluidFilter(); + } + int slot = (x - filterEX) / 18; + filter.setFluid(slot, st); + setConduitFilter(true, filter); + return true; + } + return false; } - protected void setConduitFilter(FluidFilter filter) { - eConduit.setFilter(gui.getDir(), filter, isInput()); + protected void setConduitFilter(boolean isInput, FluidFilter filter) { + eConduit.setFilter(gui.getDir(), filter, isInput); - PacketHandler.INSTANCE.sendToServer(new PacketFluidFilter(eConduit, gui.getDir(), filter, isInput())); + PacketHandler.INSTANCE.sendToServer(new PacketFluidFilter(eConduit, gui.getDir(), filter, isInput)); } - protected void setConduitChannel(DyeColor channel) { - if(isInput()) { + protected void setConduitChannel(boolean isInput, DyeColor channel) { + if(isInput) { eConduit.setInputColor(gui.getDir(), channel); } else { eConduit.setOutputColor(gui.getDir(), channel); } - PacketHandler.INSTANCE.sendToServer(new PacketFluidChannel(eConduit, gui.getDir(), isInput(), channel)); + PacketHandler.INSTANCE.sendToServer(new PacketFluidChannel(eConduit, gui.getDir(), isInput, channel)); } @Override @@ -269,47 +278,37 @@ protected void initCustomOptions() { private void updateGuiVisibility() { deactivate(); - if(isInput()) { - rsB.onGuiInit(); - colorB.onGuiInit(); - } + rsB.onGuiInit(); + colorB.onGuiInit(); if(!isEnder) { return; } - if(conduit.getConnectionMode(gui.getDir()) == ConnectionMode.DISABLED) { - channelB.detach(); - } else { - channelB.onGuiInit(); - if (isInput()) { - channelB.setColorIndex(eConduit.getInputColor(gui.getDir()).ordinal()); - } else { - channelB.setColorIndex(eConduit.getOutputColor(gui.getDir()).ordinal()); - } - } - if(isInput()) { - roundRobinB.onGuiInit(); - roundRobinB.setSelected(eConduit.isRoundRobin(gui.getDir())); - } + insertChannelB.onGuiInit(); + insertChannelB.setColorIndex(eConduit.getOutputColor(gui.getDir()).ordinal()); + extractChannelB.onGuiInit(); + extractChannelB.setColorIndex(eConduit.getInputColor(gui.getDir()).ordinal()); + roundRobinB.onGuiInit(); + roundRobinB.setSelected(eConduit.isRoundRobin(gui.getDir())); + gui.getContainer().setInventorySlotsVisible(true); if(isFilterVisible()) { - gui.getContainer().setInventorySlotsVisible(true); addFilterTooltips(); - whiteListB.onGuiInit(); - updateWhiteListButton(eConduit.getFilter(gui.getDir(), isInput())); - } else { - gui.getContainer().setInventorySlotsVisible(false); + insertWhiteListB.onGuiInit(); + extractWhiteListB.onGuiInit(); + updateWhiteListButtons(); } + } - ConnectionMode mode = con.getConnectionMode(gui.getDir()); - if(mode == ConnectionMode.IN_OUT) { - inOutNextB.onGuiInit(); - } + private void updateWhiteListButtons() { + updateWhiteListButton(eConduit.getFilter(gui.getDir(), false), false); + updateWhiteListButton(eConduit.getFilter(gui.getDir(), true), true); } - private void updateWhiteListButton(FluidFilter filter) { + private void updateWhiteListButton(FluidFilter filter, boolean isInput) { + IconButton whiteListB = isInput ? extractWhiteListB : insertWhiteListB; if(filter != null && filter.isBlacklist()) { whiteListB.setIcon(IconEIO.FILTER_BLACKLIST); whiteListB.setToolTip(EnderIO.lang.localize("gui.conduit.fluid.blacklist")); @@ -324,9 +323,9 @@ public void deactivate() { rsB.detach(); colorB.detach(); + gui.getContainer().setInventorySlotsVisible(false); if(isEnder) { roundRobinB.detach(); - gui.getContainer().setInventorySlotsVisible(false); if(filterToolTips != null) { for (GuiToolTip tt : filterToolTips) { if(tt != null) { @@ -334,43 +333,53 @@ public void deactivate() { } } } - inOutNextB.detach(); - whiteListB.detach(); - channelB.detach(); + insertWhiteListB.detach(); + extractWhiteListB.detach(); + insertChannelB.detach(); + extractChannelB.detach(); } } @Override protected void renderCustomOptions(int top, float par1, int par2, int par3) { - boolean isInput = isInput(); if(isEnder && isFilterVisible()) { - String inOutStr = EnderIO.lang.localize("gui.conduit.ioMode.output"); - if(conduit.getConnectionMode(gui.getDir()) == ConnectionMode.IN_OUT) { - inOutStr = inOutShowIn ? EnderIO.lang.localize("gui.conduit.ioMode.input") : EnderIO.lang.localize("gui.conduit.ioMode.output"); - } else if(conduit.getConnectionMode(gui.getDir()) == ConnectionMode.INPUT){ - inOutStr = EnderIO.lang.localize("gui.conduit.ioMode.input"); - } int x = left; int y = top; - gui.getFontRenderer().drawString(inOutStr, x, y, ColorUtil.getRGB(Color.DARK_GRAY)); GL11.glColor3f(1, 1, 1); gui.bindGuiTexture(1); - gui.drawTexturedModalRect(gui.getGuiLeft(), gui.getGuiTop() + 55, 0, 55, gui.getXSize(), 145); + //gui.drawTexturedModalRect(gui.getGuiLeft(), gui.getGuiTop() + 55, 0, 55, gui.getXSize(), 145); FontRenderer fr = gui.getFontRenderer(); int sw = fr.getStringWidth(filterStr); - x = (gui.width / 2) - sw / 2; + x = left + 50 - sw/2; y = top + 20; fr.drawString(filterStr, x, y, ColorUtil.getRGB(Color.DARK_GRAY)); + x = left + 150 - sw/2; + fr.drawString(filterStr, x, y, ColorUtil.getRGB(Color.DARK_GRAY)); - x = gui.getGuiLeft() + filterX; + x = gui.getGuiLeft() + filterIX; y = gui.getGuiTop() + filterY; GL11.glColor3f(1, 1, 1); gui.bindGuiTexture(); gui.drawTexturedModalRect(x, y, 24, 238, 90, 18); - FluidFilter filter = eConduit.getFilter(gui.getDir(), isInput); + FluidFilter filter = eConduit.getFilter(gui.getDir(), false); + if(filter != null && !filter.isEmpty()) { + for (int i = 0; i < filter.size(); i++) { + FluidStack f = filter.getFluidStackAt(i); + if(f != null) { + renderFluid(f, x + (i * 18), y); + } + } + } + + x = gui.getGuiLeft() + filterEX; + GL11.glColor3f(1, 1, 1); + gui.bindGuiTexture(); + gui.drawTexturedModalRect(x, y, 24, 238, 90, 18); + + filter = eConduit.getFilter(gui.getDir(), true); if(filter != null && !filter.isEmpty()) { for (int i = 0; i < filter.size(); i++) { FluidStack f = filter.getFluidStackAt(i); @@ -395,26 +404,19 @@ private void renderFluid(FluidStack f, int x, int y) { } - private boolean isInput() { - ConnectionMode mode = conduit.getConnectionMode(gui.getDir()); - return (mode == ConnectionMode.IN_OUT && inOutShowIn) || (mode == ConnectionMode.INPUT); - } - private boolean isFilterVisible() { - if(!isEnder) { - return false; - } - ConnectionMode mode = conduit.getConnectionMode(gui.getDir()); - return mode == ConnectionMode.INPUT || mode == ConnectionMode.OUTPUT || mode == ConnectionMode.IN_OUT; + return isEnder; } private class FilterToolTip extends GuiToolTip { int index; + boolean isInput; - public FilterToolTip(Rectangle bounds, int index) { + public FilterToolTip(Rectangle bounds, int index, boolean isInput) { super(bounds, (String[]) null); this.index = index; + this.isInput = isInput; } @Override @@ -422,7 +424,7 @@ public List getToolTipText() { if(!isFilterVisible()) { return null; } - FluidFilter filter = eConduit.getFilter(gui.getDir(), isInput()); + FluidFilter filter = eConduit.getFilter(gui.getDir(), isInput); if(filter == null) { return null; } diff --git a/src/main/java/crazypants/enderio/conduit/gui/item/BasicItemFilterGui.java b/src/main/java/crazypants/enderio/conduit/gui/item/BasicItemFilterGui.java index bfc94b7360..a8c75e346d 100644 --- a/src/main/java/crazypants/enderio/conduit/gui/item/BasicItemFilterGui.java +++ b/src/main/java/crazypants/enderio/conduit/gui/item/BasicItemFilterGui.java @@ -13,38 +13,41 @@ import org.lwjgl.opengl.GL11; public class BasicItemFilterGui implements IItemFilterGui { - + private static final int ID_WHITELIST = GuiExternalConnection.nextButtonId(); private static final int ID_NBT = GuiExternalConnection.nextButtonId(); private static final int ID_META = GuiExternalConnection.nextButtonId(); private static final int ID_ORE_DICT = GuiExternalConnection.nextButtonId(); - private static final int ID_STICKY = GuiExternalConnection.nextButtonId(); + private static final int ID_STICKY = GuiExternalConnection.nextButtonId(); private static final int ID_FUZZY = GuiExternalConnection.nextButtonId(); - + private final GuiContainerBaseEIO gui; - + private final ToggleButton useMetaB; private final ToggleButton useNbtB; private final IconButton whiteListB; private final ToggleButton useOreDictB; private final ToggleButton stickyB; private final CycleButton fuzzyB; - + final boolean isAdvanced; final boolean isStickyModeAvailable; - + private final IItemFilterContainer filterContainer; private final ItemFilter filter; - + private int buttonIdOffset; private int xOffset; private int yOffset; - public BasicItemFilterGui(GuiContainerBaseEIO gui, IItemFilterContainer filterContainer, boolean isStickyModeAvailable) { - this(gui, filterContainer, isStickyModeAvailable, 32, 68, 0); + private boolean isInput; + + public BasicItemFilterGui(GuiContainerBaseEIO gui, IItemFilterContainer filterContainer, boolean isStickyModeAvailable, boolean isInput) { + this(gui, filterContainer, isStickyModeAvailable, isInput, isInput ? 6 : 104, 96, isInput ? 0 : 256); } public BasicItemFilterGui(GuiContainerBaseEIO gui, IItemFilterContainer filterContainer, boolean isStickyModeAvailable, + boolean isInput, int xOffset, int yOffset, int buttonIdOffset) { this.gui = gui; @@ -53,44 +56,43 @@ public BasicItemFilterGui(GuiContainerBaseEIO gui, IItemFilterContainer filterCo this.xOffset = xOffset; this.yOffset = yOffset; this.buttonIdOffset = buttonIdOffset; + this.isInput = isInput; filter = filterContainer.getItemFilter(); - + isAdvanced = filter.isAdvanced(); - - int butLeft = xOffset + 92; + + int butLeft = xOffset; int x = butLeft; - int y = yOffset + 1; + int y = yOffset + (isAdvanced ? 40 : 20); whiteListB = new IconButton(gui, ID_WHITELIST + buttonIdOffset, x, y, IconEIO.FILTER_WHITELIST); whiteListB.setToolTip(getWhitelistTooltips(false)); - x += 20; + x += 16; useMetaB = new ToggleButton(gui, ID_META + buttonIdOffset, x, y, IconEIO.FILTER_META_OFF, IconEIO.FILTER_META); useMetaB.setSelectedToolTip(EnderIO.lang.localize("gui.conduit.item.matchMetaData")); useMetaB.setUnselectedToolTip(EnderIO.lang.localize("gui.conduit.item.ignoreMetaData")); useMetaB.setPaintSelectedBorder(false); - x += 20; + x += 16; stickyB = new ToggleButton(gui, ID_STICKY + buttonIdOffset, x, y, IconEIO.FILTER_STICKY_OFF, IconEIO.FILTER_STICKY); stickyB.setSelectedToolTip(EnderIO.lang.localizeList("gui.conduit.item.stickyEnabled")); stickyB.setUnselectedToolTip(EnderIO.lang.localize("gui.conduit.item.stickyDisbaled")); stickyB.setPaintSelectedBorder(false); - y += 20; - x = butLeft; - + if(isStickyModeAvailable) x += 16; useOreDictB = new ToggleButton(gui, ID_ORE_DICT + buttonIdOffset, x, y, IconEIO.FILTER_ORE_DICT_OFF, IconEIO.FILTER_ORE_DICT); useOreDictB.setSelectedToolTip(EnderIO.lang.localize("gui.conduit.item.oreDicEnabled")); useOreDictB.setUnselectedToolTip(EnderIO.lang.localize("gui.conduit.item.oreDicDisabled")); useOreDictB.setPaintSelectedBorder(false); - x += 20; + x += 16; useNbtB = new ToggleButton(gui, ID_NBT + buttonIdOffset, x, y, IconEIO.FILTER_NBT_OFF, IconEIO.FILTER_NBT); useNbtB.setSelectedToolTip(EnderIO.lang.localize("gui.conduit.item.matchNBT")); useNbtB.setUnselectedToolTip(EnderIO.lang.localize("gui.conduit.item.ignoreNBT")); useNbtB.setPaintSelectedBorder(false); - x += 20; + x += 16; fuzzyB = new CycleButton(gui, ID_FUZZY + buttonIdOffset, x, y, FuzzyMode.class); } @@ -104,9 +106,9 @@ public void run() { } @Override - public void mouseClicked(int x, int y, int par3) { + public void mouseClicked(int x, int y, int par3) { } - + @Override public void updateButtons() { ItemFilter activeFilter = filter; @@ -117,7 +119,7 @@ public void updateButtons() { useOreDictB.onGuiInit(); useOreDictB.setSelected(activeFilter.isUseOreDict()); - + if(isStickyModeAvailable) { stickyB.onGuiInit(); stickyB.setSelected(activeFilter.isSticky()); @@ -138,10 +140,10 @@ public void updateButtons() { whiteListB.setIcon(IconEIO.FILTER_WHITELIST); } } - + @Override public void actionPerformed(GuiButton guiButton) { - + if(guiButton.id == ID_META + buttonIdOffset) { filter.setMatchMeta(useMetaB.isSelected()); sendFilterChange(); @@ -160,16 +162,16 @@ public void actionPerformed(GuiButton guiButton) { } else if(guiButton.id == ID_WHITELIST + buttonIdOffset) { filter.setBlacklist(!filter.isBlacklist()); sendFilterChange(); - } + } } - + private void sendFilterChange() { updateButtons(); filterContainer.onFilterChanged(); } - + @Override - public void deactivate() { + public void deactivate() { useNbtB.detach(); useMetaB.detach(); useOreDictB.detach(); @@ -177,13 +179,13 @@ public void deactivate() { stickyB.detach(); fuzzyB.detach(); } - + @Override public void renderCustomOptions(int top, float par1, int par2, int par3) { GL11.glColor3f(1, 1, 1); gui.bindGuiTexture(1); gui.drawTexturedModalRect(gui.getGuiLeft() + xOffset, gui.getGuiTop() + yOffset, 0, 238, 18 * 5, 18); - if(filter.isAdvanced()) { + if(filter.isAdvanced()) { gui.drawTexturedModalRect(gui.getGuiLeft() + xOffset, gui.getGuiTop() + yOffset + 20, 0, 238, 18 * 5, 18); } } diff --git a/src/main/java/crazypants/enderio/conduit/gui/item/BigItemFilterGui.java b/src/main/java/crazypants/enderio/conduit/gui/item/BigItemFilterGui.java index bbc7175615..8fc11a2e03 100644 --- a/src/main/java/crazypants/enderio/conduit/gui/item/BigItemFilterGui.java +++ b/src/main/java/crazypants/enderio/conduit/gui/item/BigItemFilterGui.java @@ -44,11 +44,11 @@ public class BigItemFilterGui implements IItemFilterGui { private int xOffset; private int yOffset; - public BigItemFilterGui(GuiContainerBaseEIO gui, IItemFilterContainer filterContainer, boolean isStickyModeAvailable) { - this(gui, filterContainer, isStickyModeAvailable, 32, 48, 0); + public BigItemFilterGui(GuiContainerBaseEIO gui, IItemFilterContainer filterContainer, boolean isStickyModeAvailable, boolean isInput) { + this(gui, filterContainer, isStickyModeAvailable, isInput, isInput ? 6 : 104, 96, isInput ? 0 : 256); } - public BigItemFilterGui(GuiContainerBaseEIO gui, IItemFilterContainer filterContainer, boolean isStickyModeAvailable, + public BigItemFilterGui(GuiContainerBaseEIO gui, IItemFilterContainer filterContainer, boolean isStickyModeAvailable, boolean isInput, int xOffset, int yOffset, int buttonIdOffset) { this.gui = gui; @@ -62,38 +62,45 @@ public BigItemFilterGui(GuiContainerBaseEIO gui, IItemFilterContainer filterCont isAdvanced = filter.isAdvanced(); - int butLeft = xOffset + 92+ 54; + int butLeft = xOffset; int x = butLeft; - int y = yOffset + 40; + int y = yOffset - 8; whiteListB = new IconButton(gui, ID_WHITELIST + buttonIdOffset, x, y, IconEIO.FILTER_WHITELIST); whiteListB.setToolTip(EnderIO.lang.localize("gui.conduit.item.whitelist")); - y -= 20; + x += 16; useMetaB = new ToggleButton(gui, ID_META + buttonIdOffset, x, y, IconEIO.FILTER_META_OFF, IconEIO.FILTER_META); useMetaB.setSelectedToolTip(EnderIO.lang.localize("gui.conduit.item.matchMetaData")); useMetaB.setUnselectedToolTip(EnderIO.lang.localize("gui.conduit.item.ignoreMetaData")); useMetaB.setPaintSelectedBorder(false); - y -= 20; + x += 16; useOreDictB = new ToggleButton(gui, ID_ORE_DICT + buttonIdOffset, x, y, IconEIO.FILTER_ORE_DICT_OFF, IconEIO.FILTER_ORE_DICT); useOreDictB.setSelectedToolTip(EnderIO.lang.localize("gui.conduit.item.oreDicEnabled")); useOreDictB.setUnselectedToolTip(EnderIO.lang.localize("gui.conduit.item.oreDicDisabled")); useOreDictB.setPaintSelectedBorder(false); - y -= 20; + x += 16; useNbtB = new ToggleButton(gui, ID_NBT + buttonIdOffset, x, y, IconEIO.FILTER_NBT_OFF, IconEIO.FILTER_NBT); useNbtB.setSelectedToolTip(EnderIO.lang.localize("gui.conduit.item.matchNBT")); useNbtB.setUnselectedToolTip(EnderIO.lang.localize("gui.conduit.item.ignoreNBT")); useNbtB.setPaintSelectedBorder(false); - y -= 20; + x += 16; fuzzyB = new CycleButton(gui, ID_FUZZY + buttonIdOffset, x, y, FuzzyMode.class); - x -= 20; + x += 16; stickyB = new ToggleButton(gui, ID_STICKY + buttonIdOffset, x, y, IconEIO.FILTER_STICKY_OFF, IconEIO.FILTER_STICKY); stickyB.setSelectedToolTip(EnderIO.lang.localizeList("gui.conduit.item.stickyEnabled")); stickyB.setUnselectedToolTip(EnderIO.lang.localize("gui.conduit.item.stickyDisbaled")); stickyB.setPaintSelectedBorder(false); + + this.yOffset += 8; + if (isInput) { + this.xOffset -= 50; + } else { + // + } } public void createFilterSlots() { @@ -189,10 +196,10 @@ public void renderCustomOptions(int top, float par1, int par2, int par3) { gui.drawTexturedModalRect(gui.getGuiLeft() + xOffset + 54, gui.getGuiTop() + yOffset, 0, 238, 18 * 5, 18); gui.drawTexturedModalRect(gui.getGuiLeft() + xOffset, gui.getGuiTop() + yOffset, 0, 238, 18 * 5, 18); - gui.drawTexturedModalRect(gui.getGuiLeft() + xOffset + 54, gui.getGuiTop() + yOffset + 20, 0, 238, 18 * 5, 18); - gui.drawTexturedModalRect(gui.getGuiLeft() + xOffset, gui.getGuiTop() + yOffset + 20, 0, 238, 18 * 5, 18); - gui.drawTexturedModalRect(gui.getGuiLeft() + xOffset + 54, gui.getGuiTop() + yOffset + 40, 0, 238, 18 * 5, 18); - gui.drawTexturedModalRect(gui.getGuiLeft() + xOffset, gui.getGuiTop() + yOffset + 40, 0, 238, 18 * 5, 18); + gui.drawTexturedModalRect(gui.getGuiLeft() + xOffset + 54, gui.getGuiTop() + yOffset + 18, 0, 238, 18 * 5, 18); + gui.drawTexturedModalRect(gui.getGuiLeft() + xOffset, gui.getGuiTop() + yOffset + 18, 0, 238, 18 * 5, 18); + gui.drawTexturedModalRect(gui.getGuiLeft() + xOffset + 54, gui.getGuiTop() + yOffset + 36, 0, 238, 18 * 5, 18); + gui.drawTexturedModalRect(gui.getGuiLeft() + xOffset, gui.getGuiTop() + yOffset + 36, 0, 238, 18 * 5, 18); } } diff --git a/src/main/java/crazypants/enderio/conduit/gui/item/ExistingItemFilterGui.java b/src/main/java/crazypants/enderio/conduit/gui/item/ExistingItemFilterGui.java index a4e8679f9b..93c7e324c7 100644 --- a/src/main/java/crazypants/enderio/conduit/gui/item/ExistingItemFilterGui.java +++ b/src/main/java/crazypants/enderio/conduit/gui/item/ExistingItemFilterGui.java @@ -32,12 +32,12 @@ public class ExistingItemFilterGui implements IItemFilterGui { private static final int ID_META = GuiExternalConnection.nextButtonId(); private static final int ID_ORE_DICT = GuiExternalConnection.nextButtonId(); private static final int ID_STICKY = GuiExternalConnection.nextButtonId(); - + private static final int ID_SNAPSHOT = GuiExternalConnection.nextButtonId(); private static final int ID_CLEAR = GuiExternalConnection.nextButtonId(); private static final int ID_SHOW = GuiExternalConnection.nextButtonId(); private static final int ID_MERGE = GuiExternalConnection.nextButtonId(); - + private IItemConduit itemConduit; private GuiExternalConnection gui; @@ -46,7 +46,7 @@ public class ExistingItemFilterGui implements IItemFilterGui { private ToggleButton useNbtB; private ToggleButton useOreDictB; private ToggleButton stickyB; - + private final IconButton whiteListB; private GuiButton snapshotB; @@ -56,6 +56,7 @@ public class ExistingItemFilterGui implements IItemFilterGui { private SnapshotOverlay snapshotOverlay; boolean isInput; + private int buttonIdOffset = 0; private ExistingItemFilter filter; @@ -63,6 +64,7 @@ public ExistingItemFilterGui(GuiExternalConnection gui, IItemConduit itemConduit this.gui = gui; this.itemConduit = itemConduit; this.isInput = isInput; + this.buttonIdOffset = isInput ? 0 : 256; if(isInput) { filter = (ExistingItemFilter) itemConduit.getInputFilter(gui.getDir()); @@ -70,54 +72,51 @@ public ExistingItemFilterGui(GuiExternalConnection gui, IItemConduit itemConduit filter = (ExistingItemFilter) itemConduit.getOutputFilter(gui.getDir()); } - int butLeft = 37; + int butLeft = isInput ? 6 : 104; int x = butLeft; - int y = 68; + int y = 96; - useMetaB = new ToggleButton(gui, ID_META, x, y, IconEIO.FILTER_META_OFF, IconEIO.FILTER_META); + useMetaB = new ToggleButton(gui, ID_META + buttonIdOffset, x, y, IconEIO.FILTER_META_OFF, IconEIO.FILTER_META); useMetaB.setSelectedToolTip(EnderIO.lang.localize("gui.conduit.item.matchMetaData")); useMetaB.setUnselectedToolTip(EnderIO.lang.localize("gui.conduit.item.ignoreMetaData")); useMetaB.setPaintSelectedBorder(false); - x += 20; - stickyB = new ToggleButton(gui, ID_STICKY, x, y, IconEIO.FILTER_STICKY_OFF, IconEIO.FILTER_STICKY); + x += 16; + whiteListB = new IconButton(gui, -1, x, y, IconEIO.FILTER_WHITELIST); + whiteListB.setToolTip(EnderIO.lang.localize("gui.conduit.item.whitelist")); + + x += 16; + stickyB = new ToggleButton(gui, ID_STICKY + buttonIdOffset, x, y, IconEIO.FILTER_STICKY_OFF, IconEIO.FILTER_STICKY); String[] lines = EnderIO.lang.localizeList("gui.conduit.item.stickyEnabled"); stickyB.setSelectedToolTip(lines); stickyB.setUnselectedToolTip(EnderIO.lang.localize("gui.conduit.item.stickyDisbaled")); stickyB.setPaintSelectedBorder(false); - y += 20; - x = butLeft; - - x += 20; - useNbtB = new ToggleButton(gui, ID_NBT, x, y, IconEIO.FILTER_NBT_OFF, IconEIO.FILTER_NBT); + if(!isInput) x += 16; + useNbtB = new ToggleButton(gui, ID_NBT + buttonIdOffset, x, y, IconEIO.FILTER_NBT_OFF, IconEIO.FILTER_NBT); useNbtB.setSelectedToolTip(EnderIO.lang.localize("gui.conduit.item.matchNBT")); useNbtB.setUnselectedToolTip(EnderIO.lang.localize("gui.conduit.item.ignoreNBT")); useNbtB.setPaintSelectedBorder(false); - x = butLeft; - useOreDictB = new ToggleButton(gui, ID_ORE_DICT, x, y, IconEIO.FILTER_ORE_DICT_OFF, IconEIO.FILTER_ORE_DICT); + x += 16; + useOreDictB = new ToggleButton(gui, ID_ORE_DICT + buttonIdOffset, x, y, IconEIO.FILTER_ORE_DICT_OFF, IconEIO.FILTER_ORE_DICT); useOreDictB.setSelectedToolTip(EnderIO.lang.localize("gui.conduit.item.oreDicEnabled")); useOreDictB.setUnselectedToolTip(EnderIO.lang.localize("gui.conduit.item.oreDicDisabled")); useOreDictB.setPaintSelectedBorder(false); - snapshotB = new GuiButton(ID_SNAPSHOT, 0, 0, 60, 20, EnderIO.lang.localize("gui.conduit.button.snap")); - mergeB = new GuiButton(ID_MERGE, 0, 0, 40, 20, EnderIO.lang.localize("gui.conduit.button.merge")); - clearB = new GuiButton(ID_CLEAR, 0, 0, 60, 20, EnderIO.lang.localize("gui.conduit.button.clear")); - showB = new GuiButton(ID_SHOW, 0, 0, 40, 20, EnderIO.lang.localize("gui.conduit.button.show")); - - x -= 20; - whiteListB = new IconButton(gui, -1, x, y, IconEIO.FILTER_WHITELIST); - whiteListB.setToolTip(EnderIO.lang.localize("gui.conduit.item.whitelist")); + snapshotB = new GuiButton(ID_SNAPSHOT + buttonIdOffset, 0, 0, 56, 20, EnderIO.lang.localize("gui.conduit.button.snap")); + mergeB = new GuiButton(ID_MERGE + buttonIdOffset, 0, 0, 40, 20, EnderIO.lang.localize("gui.conduit.button.merge")); + clearB = new GuiButton(ID_CLEAR + buttonIdOffset, 0, 0, 56, 20, EnderIO.lang.localize("gui.conduit.button.clear")); + showB = new GuiButton(ID_SHOW + buttonIdOffset, 0, 0, 40, 20, EnderIO.lang.localize("gui.conduit.button.show")); snapshotOverlay = new SnapshotOverlay(); gui.addOverlay(snapshotOverlay); - - + + } - + @Override - public void mouseClicked(int x, int y, int par3) { + public void mouseClicked(int x, int y, int par3) { } @Override @@ -148,22 +147,25 @@ public void updateButtons() { whiteListB.setToolTip(EnderIO.lang.localize("gui.conduit.item.whitelist")); } - int x0 = gui.getGuiLeft() + 80; - int y0 = gui.getGuiTop() + 65; - int x1 = x0 + 65; - int y1 = y0 + 22; + int butLeft = gui.getGuiLeft() + (isInput ? 5 : 104); + int x = butLeft; + int y = gui.getGuiTop() + 96 + 20; - snapshotB.xPosition = x0; - snapshotB.yPosition = y0; + snapshotB.xPosition = x; + snapshotB.yPosition = y; - mergeB.xPosition = x1; - mergeB.yPosition = y0; + x += 56; + mergeB.xPosition = x; + mergeB.yPosition = y; - clearB.xPosition = x0; - clearB.yPosition = y1; + x = butLeft; + y += 20; + clearB.xPosition = x; + clearB.yPosition = y; - showB.xPosition = x1; - showB.yPosition = y1; + x += 56; + showB.xPosition = x; + showB.yPosition = y; clearB.enabled = filter.getSnapshot() != null; showB.enabled = clearB.enabled; @@ -177,26 +179,26 @@ public void updateButtons() { @Override public void actionPerformed(GuiButton guiButton) { - if(guiButton.id == ID_META) { + if(guiButton.id == ID_META + buttonIdOffset) { filter.setMatchMeta(useMetaB.isSelected()); sendFilterChange(); - } else if(guiButton.id == ID_NBT) { + } else if(guiButton.id == ID_NBT + buttonIdOffset) { filter.setMatchNBT(useNbtB.isSelected()); sendFilterChange(); - } else if(guiButton.id == ID_STICKY) { + } else if(guiButton.id == ID_STICKY + buttonIdOffset) { filter.setSticky(stickyB.isSelected()); sendFilterChange(); - } else if(guiButton.id == ID_ORE_DICT) { + } else if(guiButton.id == ID_ORE_DICT + buttonIdOffset) { filter.setUseOreDict(useOreDictB.isSelected()); sendFilterChange(); - } else if(guiButton.id == ID_SNAPSHOT) { + } else if(guiButton.id == ID_SNAPSHOT + buttonIdOffset) { sendSnapshotPacket(PacketExistingItemFilterSnapshot.Opcode.SET); - } else if(guiButton.id == ID_CLEAR) { + } else if(guiButton.id == ID_CLEAR + buttonIdOffset) { sendSnapshotPacket(PacketExistingItemFilterSnapshot.Opcode.CLEAR); - } else if(guiButton.id == ID_MERGE) { + } else if(guiButton.id == ID_MERGE + buttonIdOffset) { sendSnapshotPacket(PacketExistingItemFilterSnapshot.Opcode.MERGE); - } else if(guiButton.id == ID_SHOW) { - showSnapshotOverlay(); + } else if(guiButton.id == ID_SHOW + buttonIdOffset) { + showSnapshotOverlay(); } else if (guiButton == whiteListB) { filter.setBlacklist(!filter.isBlacklist()); sendSnapshotPacket(filter.isBlacklist() ? PacketExistingItemFilterSnapshot.Opcode.SET_BLACK @@ -205,7 +207,7 @@ public void actionPerformed(GuiButton guiButton) { } private void showSnapshotOverlay() { - snapshotOverlay.setVisible(true); + snapshotOverlay.setVisible(true); } private void sendSnapshotPacket(PacketExistingItemFilterSnapshot.Opcode opcode) { @@ -214,14 +216,14 @@ private void sendSnapshotPacket(PacketExistingItemFilterSnapshot.Opcode opcode) private void sendFilterChange() { updateButtons(); - PacketHandler.INSTANCE.sendToServer(new PacketItemConduitFilter(itemConduit, gui.getDir())); + PacketHandler.INSTANCE.sendToServer(new PacketItemConduitFilter(itemConduit, gui.getDir())); } @Override public void deactivate() { useNbtB.detach(); useMetaB.detach(); - useOreDictB.detach(); + useOreDictB.detach(); stickyB.detach(); whiteListB.detach(); gui.removeButton(snapshotB); @@ -239,32 +241,32 @@ public void renderCustomOptions(int top, float par1, int par2, int par3) { // gui.drawTexturedModalRect(gui.getGuiLeft() + 32, gui.getGuiTop() + 86, 0, 238, 18 * 5, 18); // } } - + class SnapshotOverlay implements IGuiOverlay { boolean visible; - + @Override - public void init(IGuiScreen screen) { + public void init(IGuiScreen screen) { } @Override - public Rectangle getBounds() { + public Rectangle getBounds() { return new Rectangle(0,0,gui.width,gui.height); } @Override - public void draw(int mouseX, int mouseY, float partialTick) { + public void draw(int mouseX, int mouseY, float partialTick) { RenderHelper.enableGUIStandardItemLighting(); GL11.glEnable(GL11.GL_BLEND); RenderUtil.renderQuad2D(4, 4, 0, gui.getXSize() - 9, gui.getYSize() - 8, new Vector4f(0,0,0,1)); RenderUtil.renderQuad2D(6, 6, 0, gui.getXSize() - 13, gui.getYSize() - 12, new Vector4f(0.6,0.6,0.6,1)); - + Minecraft mc = Minecraft.getMinecraft(); RenderItem itemRenderer = new RenderItem(); - + GL11.glEnable(GL11.GL_DEPTH_TEST); - + List snapshot = filter.getSnapshot(); int x = 15; int y = 10; @@ -272,20 +274,20 @@ public void draw(int mouseX, int mouseY, float partialTick) { for(ItemStack st : snapshot) { if(st != null) { itemRenderer.renderItemAndEffectIntoGUI(mc.fontRenderer, mc.getTextureManager(), st, x, y); - //itemRender.renderItemOverlayIntoGUI(mc.fontRenderer, mc.getTextureManager(), st, x, y, s); - } + //itemRender.renderItemOverlayIntoGUI(mc.fontRenderer, mc.getTextureManager(), st, x, y, s); + } x += 20; count++; if(count % 9 == 0) { x = 15; y += 20; } - } + } } @Override public void setVisible(boolean visible) { - this.visible = visible; + this.visible = visible; } @Override @@ -299,9 +301,9 @@ public boolean handleMouseInput(int x, int y, int b) { } @Override - public boolean isMouseInBounds(int mouseX, int mouseY) { + public boolean isMouseInBounds(int mouseX, int mouseY) { return getBounds().contains(mouseX, mouseY); } - + } } diff --git a/src/main/java/crazypants/enderio/conduit/gui/item/ItemSettings.java b/src/main/java/crazypants/enderio/conduit/gui/item/ItemSettings.java index a303396349..6f8d568dfa 100644 --- a/src/main/java/crazypants/enderio/conduit/gui/item/ItemSettings.java +++ b/src/main/java/crazypants/enderio/conduit/gui/item/ItemSettings.java @@ -1,37 +1,20 @@ package crazypants.enderio.conduit.gui.item; -import java.awt.Color; -import java.awt.Rectangle; -import java.util.ArrayList; - -import net.minecraft.client.gui.FontRenderer; -import net.minecraft.client.gui.GuiButton; - -import org.lwjgl.opengl.GL11; - import com.enderio.core.client.gui.button.ColorButton; import com.enderio.core.client.gui.button.MultiIconButton; import com.enderio.core.client.gui.button.ToggleButton; -import com.enderio.core.client.gui.widget.GuiToolTip; -import com.enderio.core.client.handlers.SpecialTooltipHandler; import com.enderio.core.client.render.ColorUtil; import com.enderio.core.client.render.EnderWidget; -import com.enderio.core.client.render.RenderUtil; import com.enderio.core.common.util.DyeColor; - import crazypants.enderio.EnderIO; import crazypants.enderio.conduit.ConnectionMode; import crazypants.enderio.conduit.IConduit; import crazypants.enderio.conduit.gui.BaseSettingsPanel; import crazypants.enderio.conduit.gui.FilterChangeListener; +import crazypants.enderio.conduit.gui.FilterGuiUtil; import crazypants.enderio.conduit.gui.GuiExternalConnection; -import crazypants.enderio.conduit.item.FunctionUpgrade; import crazypants.enderio.conduit.item.IItemConduit; -import crazypants.enderio.conduit.item.filter.ExistingItemFilter; import crazypants.enderio.conduit.item.filter.IItemFilter; -import crazypants.enderio.conduit.item.filter.ItemFilter; -import crazypants.enderio.conduit.item.filter.ModItemFilter; -import crazypants.enderio.conduit.item.filter.PowerItemFilter; import crazypants.enderio.conduit.packet.PacketExtractMode; import crazypants.enderio.conduit.packet.PacketItemConduitFilter; import crazypants.enderio.gui.IconEIO; @@ -39,27 +22,26 @@ import crazypants.enderio.machine.IRedstoneModeControlable; import crazypants.enderio.machine.RedstoneControlMode; import crazypants.enderio.network.PacketHandler; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.GuiButton; +import org.lwjgl.opengl.GL11; -public class ItemSettings extends BaseSettingsPanel { +import javax.annotation.Nonnull; +import java.awt.*; - private static final int NEXT_FILTER_ID = 98932; +public class ItemSettings extends BaseSettingsPanel { private static final int ID_REDSTONE_BUTTON = 12614; - private static final int ID_COLOR_BUTTON = 179816; - private static final int ID_LOOP = 22; private static final int ID_ROUND_ROBIN = 24; private static final int ID_PRIORITY_UP = 25; private static final int ID_PRIORITY_DOWN = 26; - private static final int ID_CHANNEL = 23; - - private IItemConduit itemConduit; - - private String inputHeading; - private String outputHeading; + private static final int ID_INSERT_CHANNEL = 23; + private static final int ID_EXTRACT_CHANNEL = 27; - private final MultiIconButton nextFilterB; + private @Nonnull IItemConduit itemConduit; private final ToggleButton loopB; private final ToggleButton roundRobinB; @@ -68,71 +50,56 @@ public class ItemSettings extends BaseSettingsPanel { private final MultiIconButton priDownB; private final RedstoneModeButton rsB; - private final ColorButton colorB; + private final @Nonnull ColorButton colorB; - private ColorButton channelB; + private ColorButton insertChannelB; + private ColorButton extractChannelB; - boolean inOutShowIn = false; - - private IItemFilter activeFilter; - - private int priLeft; + private int priLeft = 46; private int priWidth = 32; - private final GuiToolTip priorityTooltip; - private final GuiToolTip speedUpgradeTooltip; - private final GuiToolTip functionUpgradeTooltip; - private final GuiToolTip filterUpgradeTooltip; + private IItemFilterGui insertFilterGui; + private IItemFilterGui extractFilterGui; - private IItemFilterGui filterGui; - public ItemSettings(final GuiExternalConnection gui, IConduit con) { - super(IconEIO.WRENCH_OVERLAY_ITEM, EnderIO.lang.localize("itemItemConduit.name"), gui, con); + public ItemSettings(@Nonnull final GuiExternalConnection gui, @Nonnull IConduit con) { + super(IconEIO.WRENCH_OVERLAY_ITEM, EnderIO.lang.localize("itemItemConduit.name"), gui, con, "filter_upgrade_settings"); itemConduit = (IItemConduit) con; + this.textureHeight += 48; - inputHeading = EnderIO.lang.localize("gui.conduit.item.extractionFilter"); - outputHeading = EnderIO.lang.localize("gui.conduit.item.insertionFilter"); - - int x = 52; + int x = leftColumn; int y = customTop; - nextFilterB = MultiIconButton.createRightArrowButton(gui, NEXT_FILTER_ID, x, y); + insertChannelB = new ColorButton(gui, ID_INSERT_CHANNEL, x, y); + insertChannelB.setColorIndex(0); + insertChannelB.setToolTipHeading(EnderIO.lang.localize("gui.conduit.item.channel")); - x = 66; - channelB = new ColorButton(gui, ID_CHANNEL, x, y); - channelB.setColorIndex(0); - channelB.setToolTipHeading(EnderIO.lang.localize("gui.conduit.item.channel")); + x = rightColumn; + extractChannelB = new ColorButton(gui, ID_EXTRACT_CHANNEL, x, y); + extractChannelB.setColorIndex(0); + extractChannelB.setToolTipHeading(EnderIO.lang.localize("gui.conduit.item.channel")); - filterUpgradeTooltip = new GuiToolTip(new Rectangle(x - 21 - 18 * 2, customTop + 3 + 16, 18, 18), EnderIO.lang.localize("gui.conduit.item.filterupgrade")) { - @Override - public boolean shouldDraw() { - return !gui.getContainer().hasFilterUpgrades(isInputVisible()) && super.shouldDraw(); - } - }; - speedUpgradeTooltip = new GuiToolTip(new Rectangle(x - 21 - 18*2, customTop + 3 + 16 + 36, 18, 18), EnderIO.lang.localize("gui.conduit.item.speedupgrade"), EnderIO.lang.localize("gui.conduit.item.speedupgrade2")) { - @Override - public boolean shouldDraw() { - return !gui.getContainer().hasSpeedUpgrades() && super.shouldDraw(); - } - }; + x += 4 + extractChannelB.getWidth(); + roundRobinB = new ToggleButton(gui, ID_ROUND_ROBIN, x, y, IconEIO.ROUND_ROBIN_OFF, IconEIO.ROUND_ROBIN); + roundRobinB.setSelectedToolTip(EnderIO.lang.localize("gui.conduit.item.roundRobinEnabled")); + roundRobinB.setUnselectedToolTip(EnderIO.lang.localize("gui.conduit.item.roundRobinDisabled")); + roundRobinB.setPaintSelectedBorder(false); - ArrayList list = new ArrayList(); - SpecialTooltipHandler.addTooltipFromResources(list, "enderio.gui.conduit.item.functionupgrade.line"); - for(FunctionUpgrade upgrade : FunctionUpgrade.values()) { - list.add(EnderIO.lang.localizeExact(upgrade.unlocName.concat(".name"))); - } - functionUpgradeTooltip = new GuiToolTip(new Rectangle(x - 21 - 18*2, customTop + 3 + 34, 18, 18), list) { - @Override - public boolean shouldDraw() { - return !gui.getContainer().hasFunctionUpgrades() && super.shouldDraw(); - } - }; + x += 4 + roundRobinB.getWidth(); + loopB = new ToggleButton(gui, ID_LOOP, x, y, IconEIO.LOOP_OFF, IconEIO.LOOP); + loopB.setSelectedToolTip(EnderIO.lang.localize("gui.conduit.item.selfFeedEnabled")); + loopB.setUnselectedToolTip(EnderIO.lang.localize("gui.conduit.item.selfFeedDisabled")); + loopB.setPaintSelectedBorder(false); - x += channelB.getWidth() + gap; - priLeft = x - 8; + y += insertChannelB.getHeight() + 6; + x = rightColumn; - rsB = new RedstoneModeButton(gui, ID_REDSTONE_BUTTON, x, y, new IRedstoneModeControlable() { + int x0 = x + 20; + colorB = new ColorButton(gui, ID_COLOR_BUTTON, x0, y); + colorB.setColorIndex(itemConduit.getExtractionSignalColor(gui.getDir()).ordinal()); + colorB.setToolTipHeading(EnderIO.lang.localize("gui.conduit.item.channel")); + rsB = new RedstoneModeButton(gui, ID_REDSTONE_BUTTON, x, y, new IRedstoneModeControlable() { @Override public void setRedstoneControlMode(RedstoneControlMode mode) { RedstoneControlMode curMode = getRedstoneControlMode(); @@ -149,286 +116,158 @@ public RedstoneControlMode getRedstoneControlMode() { } }); - x += rsB.getWidth() + gap; - colorB = new ColorButton(gui, ID_COLOR_BUTTON, x, y); - colorB.setColorIndex(itemConduit.getExtractionSignalColor(gui.getDir()).ordinal()); - colorB.setToolTipHeading(EnderIO.lang.localize("gui.conduit.item.sigCol")); - - x += gap + colorB.getWidth(); - roundRobinB = new ToggleButton(gui, ID_ROUND_ROBIN, x, y, IconEIO.ROUND_ROBIN_OFF, IconEIO.ROUND_ROBIN); - roundRobinB.setSelectedToolTip(EnderIO.lang.localize("gui.conduit.item.roundRobinEnabled")); - roundRobinB.setUnselectedToolTip(EnderIO.lang.localize("gui.conduit.item.roundRobinDisabled")); - roundRobinB.setPaintSelectedBorder(false); - - x += gap + roundRobinB.getWidth(); - loopB = new ToggleButton(gui, ID_LOOP, x, y, IconEIO.LOOP_OFF, IconEIO.LOOP); - loopB.setSelectedToolTip(EnderIO.lang.localize("gui.conduit.item.selfFeedEnabled")); - loopB.setUnselectedToolTip(EnderIO.lang.localize("gui.conduit.item.selfFeedDisabled")); - loopB.setPaintSelectedBorder(false); - - priorityTooltip = new GuiToolTip(new Rectangle(priLeft + 9, y, priWidth, 16), EnderIO.lang.localize("gui.conduit.item.priority")); - x = priLeft + priWidth + 9; priUpB = MultiIconButton.createAddButton(gui, ID_PRIORITY_UP, x, y); - priDownB = MultiIconButton.createMinusButton(gui, ID_PRIORITY_DOWN, x, y+8); + priDownB = MultiIconButton.createMinusButton(gui, ID_PRIORITY_DOWN, x, y + 8); - gui.getContainer().addFilterListener(new FilterChangeListener() { + FilterChangeListener fcl = new FilterChangeListener() { @Override public void onFilterChanged() { - filtersChanged(); + if (insertFilterGui != null) { + insertFilterGui.deactivate(); + insertFilterGui = null; + } + if (extractFilterGui != null) { + extractFilterGui.deactivate(); + extractFilterGui = null; + } + gui.clearGhostSlots(); + IItemFilter filt = gui.getContainer().getFilter(false); + if (filt != null) { + insertFilterGui = filt.getGui(gui, gui.getContainer().getInv().itemConduit, false); + } + filt = gui.getContainer().getFilter(true); + if (filt != null) { + extractFilterGui = filt.getGui(gui, gui.getContainer().getInv().itemConduit, true); + } + if (insertFilterGui != null) { + insertFilterGui.updateButtons(); + } + if (extractFilterGui != null) { + extractFilterGui.updateButtons(); + } } - }); - - } - - private String getHeading() { - ConnectionMode mode = con.getConnectionMode(gui.getDir()); - if(mode == ConnectionMode.DISABLED) { - return ""; - } - if(mode == ConnectionMode.OUTPUT) { - return outputHeading; - } - if(mode == ConnectionMode.INPUT || inOutShowIn) { - return inputHeading; - } - return outputHeading; + }; + fcl.onFilterChanged(); + gui.getContainer().addFilterListener(fcl); } @Override protected void initCustomOptions() { + gui.getContainer().setInoutSlotsVisible(true, true); + gui.getContainer().createGhostSlots(gui.getGhostSlots()); + gui.getContainer().setInventorySlotsVisible(true); updateGuiVisibility(); } private void updateGuiVisibility() { - deactivate(); - createFilterGUI(); updateButtons(); } - private void createFilterGUI() { - boolean showInput = false; - boolean showOutput = false; - - ConnectionMode mode = con.getConnectionMode(gui.getDir()); - if(mode == ConnectionMode.INPUT) { - showInput = true; - } else if(mode == ConnectionMode.OUTPUT) { - showOutput = true; - } else if(mode == ConnectionMode.IN_OUT) { - nextFilterB.onGuiInit(); - showInput = inOutShowIn; - showOutput = !inOutShowIn; - } - - if(!showInput && !showOutput) { - filterGui = null; - activeFilter = null; - } else if(showInput) { - activeFilter = itemConduit.getInputFilter(gui.getDir()); - gui.getContainer().setInventorySlotsVisible(true); - gui.getContainer().setInoutSlotsVisible(true, false); - if(activeFilter != null) { - filterGui = activeFilter.getGui(gui,itemConduit,true); - } - } else if(showOutput) { - activeFilter = itemConduit.getOutputFilter(gui.getDir()); - gui.getContainer().setInoutSlotsVisible(false, true); - gui.getContainer().setInventorySlotsVisible(true); - if(activeFilter != null) { - filterGui = activeFilter.getGui(gui,itemConduit,false); - } - } - } - - private void filtersChanged() { - deactiveFilterGUI(); - createFilterGUI(); - - if(filterGui != null) { - filterGui.updateButtons(); - } - } - private void updateButtons() { + rsB.onGuiInit(); + rsB.setMode(itemConduit.getExtractionRedstoneMode(gui.getDir())); - ConnectionMode mode = con.getConnectionMode(gui.getDir()); - if(mode == ConnectionMode.DISABLED) { - return; - } - boolean outputActive = (mode == ConnectionMode.IN_OUT && !inOutShowIn) || (mode == ConnectionMode.OUTPUT); - - if(!outputActive) { - - rsB.onGuiInit(); - rsB.setMode(itemConduit.getExtractionRedstoneMode(gui.getDir())); + loopB.onGuiInit(); + loopB.setSelected(itemConduit.isSelfFeedEnabled(gui.getDir())); + roundRobinB.onGuiInit(); + roundRobinB.setSelected(itemConduit.isRoundRobinEnabled(gui.getDir())); - colorB.onGuiInit(); - colorB.setColorIndex(itemConduit.getExtractionSignalColor(gui.getDir()).ordinal()); - } - - gui.addToolTip(filterUpgradeTooltip); - gui.addToolTip(functionUpgradeTooltip); + priUpB.onGuiInit(); + priDownB.onGuiInit(); - if(mode == ConnectionMode.IN_OUT && !outputActive) { - loopB.onGuiInit(); - loopB.setSelected(itemConduit.isSelfFeedEnabled(gui.getDir())); - } + insertChannelB.onGuiInit(); + insertChannelB.setColorIndex(itemConduit.getOutputColor(gui.getDir()).ordinal()); + extractChannelB.onGuiInit(); + extractChannelB.setColorIndex(itemConduit.getInputColor(gui.getDir()).ordinal()); - if((mode == ConnectionMode.IN_OUT && !outputActive) || mode == ConnectionMode.INPUT) { - roundRobinB.onGuiInit(); - roundRobinB.setSelected(itemConduit.isRoundRobinEnabled(gui.getDir())); - gui.addToolTip(speedUpgradeTooltip); - } - - if((mode == ConnectionMode.IN_OUT && outputActive) || mode == ConnectionMode.OUTPUT) { - priUpB.onGuiInit(); - priDownB.onGuiInit(); - gui.addToolTip(priorityTooltip); - } - - int chanCol; - if(!outputActive) { - chanCol = itemConduit.getInputColor(gui.getDir()).ordinal(); - } else { - chanCol = itemConduit.getOutputColor(gui.getDir()).ordinal(); - } - channelB.onGuiInit(); - channelB.setColorIndex(chanCol); - - if(filterGui != null) { - filterGui.updateButtons(); - } + if (insertFilterGui != null) insertFilterGui.updateButtons(); + if (extractFilterGui != null) extractFilterGui.updateButtons(); } @Override - public void actionPerformed(GuiButton guiButton) { + public void actionPerformed(@Nonnull GuiButton guiButton) { super.actionPerformed(guiButton); - if(guiButton.id == NEXT_FILTER_ID) { - inOutShowIn = !inOutShowIn; - updateGuiVisibility(); - } else if(guiButton.id == ID_COLOR_BUTTON) { - itemConduit.setExtractionSignalColor(gui.getDir(), DyeColor.values()[colorB.getColorIndex()]); + if(guiButton.id == ID_COLOR_BUTTON) { + itemConduit.setExtractionSignalColor(gui.getDir(), DyeColor.fromIndex(colorB.getColorIndex())); PacketHandler.INSTANCE.sendToServer(new PacketExtractMode(itemConduit, gui.getDir())); + return; } else if(guiButton.id == ID_LOOP) { itemConduit.setSelfFeedEnabled(gui.getDir(), !itemConduit.isSelfFeedEnabled(gui.getDir())); - sendFilterChange(); } else if(guiButton.id == ID_ROUND_ROBIN) { itemConduit.setRoundRobinEnabled(gui.getDir(), !itemConduit.isRoundRobinEnabled(gui.getDir())); - sendFilterChange(); } else if(guiButton.id == ID_PRIORITY_UP) { itemConduit.setOutputPriority(gui.getDir(), itemConduit.getOutputPriority(gui.getDir()) + 1); - sendFilterChange(); } else if(guiButton.id == ID_PRIORITY_DOWN) { itemConduit.setOutputPriority(gui.getDir(), itemConduit.getOutputPriority(gui.getDir()) - 1); - sendFilterChange(); - } else if(guiButton.id == ID_CHANNEL) { - - DyeColor col = DyeColor.values()[channelB.getColorIndex()]; - if(isInputVisible()) { - itemConduit.setInputColor(gui.getDir(), col); - } else { - itemConduit.setOutputColor(gui.getDir(), col); - } - sendFilterChange(); - } - - if(filterGui != null) { - filterGui.actionPerformed(guiButton); + } else if(guiButton.id == ID_INSERT_CHANNEL) { + DyeColor col = DyeColor.fromIndex(insertChannelB.getColorIndex()); + itemConduit.setOutputColor(gui.getDir(), col); + } else if(guiButton.id == ID_EXTRACT_CHANNEL) { + DyeColor col = DyeColor.fromIndex(extractChannelB.getColorIndex()); + itemConduit.setInputColor(gui.getDir(), col); } - } - - private void sendFilterChange() { + if (insertFilterGui != null) insertFilterGui.actionPerformed(guiButton); + if (extractFilterGui != null) extractFilterGui.actionPerformed(guiButton); PacketHandler.INSTANCE.sendToServer(new PacketItemConduitFilter(itemConduit, gui.getDir())); } @Override - public void mouseClicked(int x, int y, int par3) { - super.mouseClicked(x, y, par3); - if(filterGui != null) { - filterGui.mouseClicked(x, y, par3); - } - } - - private boolean isInputVisible() { - ConnectionMode mode = con.getConnectionMode(gui.getDir()); - return (mode == ConnectionMode.IN_OUT && inOutShowIn) || (mode == ConnectionMode.INPUT); - } - - @Override - protected void connectionModeChanged(ConnectionMode conectionMode) { - super.connectionModeChanged(conectionMode); + protected void connectionModeChanged(@Nonnull ConnectionMode mode) { + super.connectionModeChanged(mode); + PacketHandler.INSTANCE.sendToServer(new PacketExtractMode(itemConduit, gui.getDir())); updateGuiVisibility(); } @Override - protected void renderCustomOptions(int top, float par1, int par2, int par3) { - ConnectionMode mode = con.getConnectionMode(gui.getDir()); - if(mode == ConnectionMode.DISABLED) { - return; - } - - gui.bindGuiTexture(1); - gui.drawTexturedModalRect(gui.getGuiLeft(), gui.getGuiTop() + 55, 0, 55, gui.getXSize(), 145); - + protected void renderCustomOptions(int top1, float par1, int par2, int par3) { FontRenderer fr = gui.getFontRenderer(); - String heading = getHeading(); - int x = 0; - int rgb = ColorUtil.getRGB(Color.darkGray); - fr.drawString(heading, left + x, top, rgb); - - boolean outputActive = (mode == ConnectionMode.IN_OUT && !inOutShowIn) || (mode == ConnectionMode.OUTPUT); - if(outputActive) { - GL11.glColor3f(1, 1, 1); - IconEIO.map.render(EnderWidget.BUTTON_DOWN, left + priLeft, top - 5, priWidth, 16, 0, true); - String str = itemConduit.getOutputPriority(gui.getDir()) + ""; - int sw = fr.getStringWidth(str); - fr.drawString(str, left + priLeft + priWidth - sw - gap, top, ColorUtil.getRGB(Color.black)); - } else { - //draw speed upgrade slot - GL11.glColor3f(1, 1, 1); - gui.bindGuiTexture(1); - gui.drawTexturedModalRect(gui.getGuiLeft() + 9, gui.getGuiTop() + 46 +18 +18, 94, 238, 18, 18); - } - //filter upgrade slot GL11.glColor3f(1, 1, 1); - gui.bindGuiTexture(1); - gui.drawTexturedModalRect(gui.getGuiLeft() + 9, gui.getGuiTop() + 46, 94, 220, 18, 18); + IconEIO.map.render(EnderWidget.BUTTON_DOWN, left + priLeft, top1 - 5, priWidth, 16, 0, true); + String str = itemConduit.getOutputPriority(gui.getDir()) + ""; + int sw = fr.getStringWidth(str); - //function upgrade slot - gui.drawTexturedModalRect(gui.getGuiLeft() + 9, gui.getGuiTop() + 46 + 18, 112, 238, 18, 18); + String priority = EnderIO.lang.localize("gui.conduit.item.priority"); + fr.drawString(priority, left + 12, top1 + 25, ColorUtil.getRGB(Color.black)); + fr.drawString(str, left + priLeft + priWidth - sw - gap, top1 + 25, ColorUtil.getRGB(Color.black)); - if(filterGui != null) { - filterGui.renderCustomOptions(top, par1, par2, par3); - } + if (insertFilterGui != null) insertFilterGui.renderCustomOptions(top1, par1, par2, par3); + if (extractFilterGui != null) extractFilterGui.renderCustomOptions(top1, par1, par2, par3); + } + + @Override + public void mouseClicked(int x, int y, int par3) { + super.mouseClicked(x, y, par3); + if (insertFilterGui != null) insertFilterGui.mouseClicked(x, y, par3); + if (extractFilterGui != null) extractFilterGui.mouseClicked(x, y, par3); } @Override public void deactivate() { - gui.getContainer().setInventorySlotsVisible(false); + super.deactivate(); gui.getContainer().setInoutSlotsVisible(false, false); rsB.detach(); colorB.detach(); roundRobinB.detach(); loopB.detach(); - nextFilterB.detach(); priUpB.detach(); priDownB.detach(); - gui.removeToolTip(priorityTooltip); - gui.removeToolTip(speedUpgradeTooltip); - gui.removeToolTip(functionUpgradeTooltip); - gui.removeToolTip(filterUpgradeTooltip); - channelB.detach(); - deactiveFilterGUI(); + insertChannelB.detach(); + extractChannelB.detach(); + gui.getContainer().setInventorySlotsVisible(false); + if (insertFilterGui != null) insertFilterGui.deactivate(); + if (extractFilterGui != null) extractFilterGui.deactivate(); } - private void deactiveFilterGUI() { - if(filterGui != null) { - filterGui.deactivate(); - filterGui = null; - } - gui.clearGhostSlots(); + @Override + protected boolean hasFilters() { + return true; + } + + @Override + protected boolean hasUpgrades() { + return true; } } diff --git a/src/main/java/crazypants/enderio/conduit/gui/item/ModItemFilterGui.java b/src/main/java/crazypants/enderio/conduit/gui/item/ModItemFilterGui.java index c9e2fbe257..89e2ee678d 100644 --- a/src/main/java/crazypants/enderio/conduit/gui/item/ModItemFilterGui.java +++ b/src/main/java/crazypants/enderio/conduit/gui/item/ModItemFilterGui.java @@ -27,13 +27,13 @@ public class ModItemFilterGui implements IItemFilterGui { private final IItemConduit itemConduit; private final GuiExternalConnection gui; - + boolean isInput; private final ModItemFilter filter; - + private final Rectangle[] inputBounds; - + private final IconButton[] deleteButs; private final IconButton whiteListB; @@ -42,47 +42,45 @@ public class ModItemFilterGui implements IItemFilterGui { private final int tfWidth; private final int tfTextureX; private final int tfTextureY; - + public ModItemFilterGui(GuiExternalConnection gui, IItemConduit itemConduit, boolean isInput) { this.gui = gui; this.itemConduit = itemConduit; this.isInput = isInput; - + int butLeft = isInput ? 5 : 106; + int x = butLeft; + int y = 96; + if(isInput) { filter = (ModItemFilter) itemConduit.getInputFilter(gui.getDir()); - inputOffsetX = 50; - tfWidth = 96; - tfTextureX = 120; - tfTextureY = 214; } else { filter = (ModItemFilter) itemConduit.getOutputFilter(gui.getDir()); - inputOffsetX = 32; - tfWidth = 114; - tfTextureX = 120; - tfTextureY = 238; } - - + inputOffsetX = x; + tfWidth = 52; + tfTextureX = 120; + tfTextureY = 214; + inputBounds = new Rectangle[] { - new Rectangle(inputOffsetX,47,16,16), - new Rectangle(inputOffsetX,68,16,16), - new Rectangle(inputOffsetX,89,16,16) + new Rectangle(inputOffsetX,y,16,16), + new Rectangle(inputOffsetX,y + 18,16,16), + new Rectangle(inputOffsetX,y + 36,16,16) }; - - deleteButs = new IconButton[inputBounds.length]; + + deleteButs = new IconButton[inputBounds.length]; for(int i=0; i < deleteButs.length; i++) { Rectangle r = inputBounds[i]; IconButton but = new IconButton(gui, GuiExternalConnection.nextButtonId(), r.x + 19, r.y, IconEIO.MINUS); deleteButs[i] = but; } - - whiteListB = new IconButton(gui, -1, inputOffsetX - 19, 89, IconEIO.FILTER_WHITELIST); + + whiteListB = new IconButton(gui, -1, x + 64, y - 25, IconEIO.FILTER_WHITELIST); whiteListB.setToolTip(EnderIO.lang.localize("gui.conduit.item.whitelist")); } @Override - public void deactivate() { + public void deactivate() { for(IconButton but : deleteButs) { but.detach(); } @@ -109,7 +107,7 @@ public void updateButtons() { public void actionPerformed(GuiButton guiButton) { for(int i=0; i < deleteButs.length; i++) { IconButton but = deleteButs[i]; - if(but.id == guiButton.id) { + if(but == guiButton) { setMod(i, null); return; } @@ -120,7 +118,7 @@ public void actionPerformed(GuiButton guiButton) { } @Override - public void renderCustomOptions(int top, float par1, int par2, int par3) { + public void renderCustomOptions(int top, float par1, int par2, int par3) { GL11.glColor3f(1, 1, 1); gui.bindGuiTexture(); for(Rectangle r : inputBounds) { @@ -128,8 +126,8 @@ public void renderCustomOptions(int top, float par1, int par2, int par3) { gui.drawTexturedModalRect(gui.getGuiLeft() + r.x - 1, gui.getGuiTop() + r.y - 1, 24, 214, 18, 18); //text box gui.drawTexturedModalRect(gui.getGuiLeft() + r.x + 38, gui.getGuiTop() + r.y - 1, tfTextureX, tfTextureY, tfWidth, 18); - } - + } + FontRenderer fr = Minecraft.getMinecraft().fontRenderer; for(int i=0;i slots, int xOffset, int yOffset, Ru public int getSlotCount() { return 0; } - + public void setSnapshot(NetworkedInventory ni) { snapshot = new ArrayList(); mergeSnapshot(ni); @@ -201,7 +201,7 @@ public IItemFilterGui getGui(GuiExternalConnection gui, IItemConduit itemConduit @Override public void readFromNBT(NBTTagCompound nbtRoot) { readSettingsFromNBT(nbtRoot); - + if(nbtRoot.hasKey("snapshot")) { snapshot = new ArrayList(); NBTTagList itemList = (NBTTagList)nbtRoot.getTag("snapshot"); @@ -212,7 +212,7 @@ public void readFromNBT(NBTTagCompound nbtRoot) { snapshot.add(itemStack); } } - + } else { snapshot = null; } @@ -229,9 +229,9 @@ protected void readSettingsFromNBT(NBTTagCompound nbtRoot) { @Override public void writeToNBT(NBTTagCompound nbtRoot) { writeSettingToNBT(nbtRoot); - + if(snapshot != null) { - + NBTTagList itemList = new NBTTagList(); for (ItemStack item : snapshot) { if(item != null) { @@ -241,7 +241,7 @@ public void writeToNBT(NBTTagCompound nbtRoot) { } } nbtRoot.setTag("snapshot", itemList); - + } } @@ -289,4 +289,8 @@ public void readFromByteBuf(ByteBuf buf) { } + @Override + public String getUnlocalizedName() { + return "gui.existing_item_filter"; + } } diff --git a/src/main/java/crazypants/enderio/conduit/item/filter/IItemFilter.java b/src/main/java/crazypants/enderio/conduit/item/filter/IItemFilter.java index bbfdde2cd4..8cdfae0223 100644 --- a/src/main/java/crazypants/enderio/conduit/item/filter/IItemFilter.java +++ b/src/main/java/crazypants/enderio/conduit/item/filter/IItemFilter.java @@ -47,4 +47,8 @@ public interface IItemFilter { int getSlotCount(); + default String getUnlocalizedName() { + return "gui.basic_item_filter"; + } + } diff --git a/src/main/java/crazypants/enderio/conduit/item/filter/ItemFilter.java b/src/main/java/crazypants/enderio/conduit/item/filter/ItemFilter.java index 760542acb6..22e8c24637 100644 --- a/src/main/java/crazypants/enderio/conduit/item/filter/ItemFilter.java +++ b/src/main/java/crazypants/enderio/conduit/item/filter/ItemFilter.java @@ -287,7 +287,7 @@ public void writeToNBT(NBTTagCompound nbtRoot) { @SideOnly(Side.CLIENT) public IItemFilterGui getGui(GuiExternalConnection gui, IItemConduit itemConduit, boolean isInput) { ItemConduitFilterContainer cont = new ItemConduitFilterContainer(itemConduit, gui.getDir(), isInput); - BasicItemFilterGui basicItemFilterGui = new BasicItemFilterGui(gui, cont, !isInput); + BasicItemFilterGui basicItemFilterGui = new BasicItemFilterGui(gui, cont, !isInput, isInput); basicItemFilterGui.createFilterSlots(); return basicItemFilterGui; } @@ -452,6 +452,11 @@ public String toString() { return "ItemFilter [isAdvanced=" + isAdvanced + ", items=" + Arrays.toString(items) + "]"; } + @Override + public String getUnlocalizedName() { + return isAdvanced ? "enderio.gui.advanced_item_filter" : "gui.basic_item_filter"; + } + class ItemFilterGhostSlot extends GhostSlot { private final int slot; private final Runnable cb; diff --git a/src/main/java/crazypants/enderio/conduit/item/filter/ItemFilterBig.java b/src/main/java/crazypants/enderio/conduit/item/filter/ItemFilterBig.java index 9138f1ca3a..1a20255186 100644 --- a/src/main/java/crazypants/enderio/conduit/item/filter/ItemFilterBig.java +++ b/src/main/java/crazypants/enderio/conduit/item/filter/ItemFilterBig.java @@ -32,7 +32,7 @@ public String getInventoryName() { @SideOnly(Side.CLIENT) public IItemFilterGui getGui(GuiExternalConnection gui, IItemConduit itemConduit, boolean isInput) { ItemConduitFilterContainer cont = new ItemConduitFilterContainer(itemConduit, gui.getDir(), isInput); - BigItemFilterGui bigItemFilterGui = new BigItemFilterGui(gui, cont, !isInput); + BigItemFilterGui bigItemFilterGui = new BigItemFilterGui(gui, cont, !isInput, isInput); bigItemFilterGui.createFilterSlots(); return bigItemFilterGui; } @@ -46,7 +46,7 @@ public void createGhostSlots(List slots, int xOffset, int yOffset, Ru for (int row = 0; row < numRows; ++row) { for (int col = 0; col < 8; ++col) { int x = leftX + col * 18; - int y = topY + row * 20; + int y = topY + row * 18; slots.add(new ItemFilterGhostSlot(index, x, y, cb)); index++; } @@ -66,4 +66,8 @@ public String toString() { return "Big"+super.toString(); } + @Override + public String getUnlocalizedName() { + return isAdvanced() ? "gui.big_advanced_item_filter" : "gui.big_item_filter"; + } } diff --git a/src/main/java/crazypants/enderio/conduit/item/filter/ModItemFilter.java b/src/main/java/crazypants/enderio/conduit/item/filter/ModItemFilter.java index d049cf548b..7eae245044 100644 --- a/src/main/java/crazypants/enderio/conduit/item/filter/ModItemFilter.java +++ b/src/main/java/crazypants/enderio/conduit/item/filter/ModItemFilter.java @@ -163,4 +163,8 @@ public void readFromByteBuf(ByteBuf buf) { readFromNBT(tag); } + @Override + public String getUnlocalizedName() { + return "gui.mod_item_filter"; + } } diff --git a/src/main/java/crazypants/enderio/conduit/item/filter/PowerItemFilter.java b/src/main/java/crazypants/enderio/conduit/item/filter/PowerItemFilter.java index b3af4f9aa1..e8f402fa1b 100644 --- a/src/main/java/crazypants/enderio/conduit/item/filter/PowerItemFilter.java +++ b/src/main/java/crazypants/enderio/conduit/item/filter/PowerItemFilter.java @@ -36,6 +36,11 @@ public CmpMode next() { CmpMode[] values = values(); return values[(ordinal() + 1) % values.length]; } + + public CmpMode prev() { + CmpMode[] values = values(); + return values[(ordinal() - 1 + values.length) % values.length]; + } } public static final int MAX_LEVEL = 4; @@ -150,4 +155,9 @@ public void readFromByteBuf(ByteBuf buf) { NBTTagCompound settingsTag = NetworkUtil.readNBTTagCompound(buf); readSettingsFromNBT(settingsTag); } + + @Override + public String getUnlocalizedName() { + return "gui.power_item_filter"; + } } diff --git a/src/main/java/crazypants/enderio/machine/transceiver/gui/FilterTab.java b/src/main/java/crazypants/enderio/machine/transceiver/gui/FilterTab.java index 3bb0dd124a..2f1c1c437f 100644 --- a/src/main/java/crazypants/enderio/machine/transceiver/gui/FilterTab.java +++ b/src/main/java/crazypants/enderio/machine/transceiver/gui/FilterTab.java @@ -36,9 +36,9 @@ public class FilterTab implements ITabPanel { FilterTab(GuiTransceiver parent) { this.parent = parent; container = parent.getContainer(); - sendGui = new BasicItemFilterGui(parent, new FilterContainer(parent.getTransciever(), true), false, container.getFilterOffset().x, + sendGui = new BasicItemFilterGui(parent, new FilterContainer(parent.getTransciever(), true), false, true, container.getFilterOffset().x, container.getFilterOffset().y, 0); - recGui = new BasicItemFilterGui(parent, new FilterContainer(parent.getTransciever(), false), false, container.getFilterOffset().x, + recGui = new BasicItemFilterGui(parent, new FilterContainer(parent.getTransciever(), false), false, false, container.getFilterOffset().x, container.getFilterOffset().y, 20); sendRecB = MultiIconButton.createRightArrowButton(parent, 8888, container.getFilterOffset().x + 79, container.getFilterOffset().y - 20); diff --git a/src/main/resources/assets/enderio/lang/en_US.lang b/src/main/resources/assets/enderio/lang/en_US.lang index ba83d0901d..830088e6e1 100644 --- a/src/main/resources/assets/enderio/lang/en_US.lang +++ b/src/main/resources/assets/enderio/lang/en_US.lang @@ -1171,6 +1171,83 @@ enderio.gui.spawnGurad.showRange=Show Range enderio.gui.spawnGurad.hideRange=Hide Range enderio.gui.spawnGurad.range=Range: +# Filters +enderio.gui.item_filter.damage.disabled=Ignore Damage +enderio.gui.item_filter.damage.damage_00_25=Up to 25% Damaged +enderio.gui.item_filter.damage.damage_25_00=More than 25% Damaged +enderio.gui.item_filter.damage.damage_00_50=Up to 50% Damaged +enderio.gui.item_filter.damage.damage_50_00=More than 50% Damaged +enderio.gui.item_filter.damage.damage_00_75=Up to 75% Damaged +enderio.gui.item_filter.damage.damage_75_00=More than 75% Damaged +enderio.gui.item_filter.damage.damage_00_00=Not Damaged +enderio.gui.item_filter.damage.damage_01_00=Damaged +enderio.gui.item_filter.damage.damage_yes=Can be Damaged +enderio.gui.item_filter.damage.damage_not=Cannot be Damaged + +enderio.gui.edit_item_filter=Edit Filter Settings +enderio.gui.item_filter.close=Close Filter +enderio.gui.item_filter.close2=Go back to previous inventory + +enderio.gui.item_filter.whitelist=Whitelist +enderio.gui.item_filter.blacklist=Blacklist +enderio.gui.item_filter.match_meta=Match Metadata +enderio.gui.item_filter.ignore_meta=Ignore Metadata +enderio.gui.item_filter.sticky_enabled=Sticky Mode Enabled +enderio.gui.item_filter.sticky_enabled2=Selected items will only be sent to this or other sticky outputs +enderio.gui.item_filter.sticky_disabled=Sticky Mode Disabled +enderio.gui.item_filter.ore_dic_enabled=Ore Dictionary Enabled +enderio.gui.item_filter.ore_dic_disabled=Ore Dictionary Disabled +enderio.gui.item_filter.match_nbt=Match NBT +enderio.gui.item_filter.ignore_nbt=Ignore NBT + +enderio.gui.existing.item_filter.snapshot=Snapshot +enderio.gui.existing.item_filter.merge=Merge +enderio.gui.existing.item_filter.clear=Clear +enderio.gui.existing.item_filter.show=Show +enderio.gui.existing.item_filter.snapshot2=Optional: If no snapshot is set, the inventory content will be used as filter +enderio.gui.existing.item_filter.merge2=Merge the current snapshot with a new one +enderio.gui.existing.item_filter.clear2=Clear the snapshot +enderio.gui.existing.item_filter.show2=Show the current snapshot +enderio.item.item_existing_item_filter.filter_not_updated=Filter not updated +enderio.item.item_existing_item_filter.filter_updated=Filter updated + +enderio.gui.basic_item_filter=Basic Item Filter +enderio.gui.advanced_item_filter=Advanced Item Filter +enderio.gui.limited_item_filter=Limited Item Filter +enderio.gui.big_item_filter=Big Item Filter +# Note big_advanced_item_filter doesn't have enough space for the full name +enderio.gui.big_advanced_item_filter=Filter +enderio.gui.existing_item_filter=Existing Item Filter +enderio.gui.mod_item_filter=Mod Item Filter +enderio.gui.power_item_filter=Power Item Filter +enderio.gui.species_item_filter=Species Item Filter +enderio.gui.soul_filter_normal=Soul Item Filter +enderio.gui.soul_filter_big=Big Soul Item Filter +enderio.gui.enchantment_filter_normal=Enchantment Item Filter +enderio.gui.enchantment_filter_big=Big Enchantment Item Filter + +enderio.gui.fluid_filter=Basic Fluid Filter + +enderio.gui.redstone_filter.and=Redstone AND Filter +enderio.gui.redstone_filter.or=Redstone OR Filter +enderio.gui.redstone_filter.nor=Redstone NOR Filter +enderio.gui.redstone_filter.nand=Redstone NAND Filter +enderio.gui.redstone_filter.xor=Redstone XOR Filter +enderio.gui.redstone_filter.xnor=Redstone XNOR Filter +enderio.gui.redstone_filter.counting=Redstone Counting Filter +enderio.gui.redstone_filter.timer=Redstone Timer Filter + +enderio.gui.mod.item_filter.delete=Delete +enderio.gui.mod.item_filter.slot=Input Slot + +enderio.gui.power.item_filter.compare=Comparison Mode +enderio.gui.power.item_filter.percent=Power Percentage + +enderio.gui.redstone_filter.signal_color=Redstone Signal Color +enderio.gui.redstone_filter.input_signal=Input Signal +enderio.gui.redstone_filter.count=Count +enderio.gui.redstone_filter.time=Time + #conduits enderio.gui.conduit.ioMode=Mode enderio.gui.conduit.ioMode.inOut=In / Out diff --git a/src/main/resources/assets/enderio/textures/gui/23/advanced_item_filter.png b/src/main/resources/assets/enderio/textures/gui/23/advanced_item_filter.png new file mode 100644 index 0000000000000000000000000000000000000000..ca95960876c3aa27b88ad5694aa5bf84dfd1439c GIT binary patch literal 1722 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|G$6%Z;_2(k{)n4V)P%R)X+;lE zh_k>WvY3HEZXXCUPTbX32NYyUcl32+VA$Bt{U?!?fq~7_)5S5Q;?~_LcpVCG%MlenC-1&29M|b3_%496PkW6X2{tuFr{zJuLZllsxwwxdoOA`Z+@);1B3sk z$Mp;SSPmF}Q`z6l)WE{P;K9IvMlE7yU=WdEU|8?~=tEZahIsY|_x)Lz8g>DhEDv@w zeLvp)J+=PhJV6GQhR@&sxi{W^+`8Mcu9S~qKj(qI1H0>fCm&k9pL2>dgBZgPdA9HA z|B3>b4*X)NRMl9k;%E{E8t1L&6!quZE>O3=9&RgKK?cfd(9V6Cxjc9B7&$eUtzl{@eV; ztK{d8m;ah!#n!;gFyWjOILLr9>A&CXSqX8649kI;b&+PJU{wqZJvYHVVqi!vTh+fZ znStTJjJdCpUr8`97^Klh2_Hkkf411#H#L920S0vKrAX8WAR>+ir4nFj)ti30==$rc zeRG$}GKes3*vqJ$+b?UaZ4FEpb05e8L)-5IFx4ffSFkfMY!Kc9^!E+Ud%(2#hUGml zsh2gC14-+HBq$GHIq;8dja}KBH8uflb%;!l~FJ@=>$4Ny?Fx}L}aN~Z%)#H70 zr?NA&+B431IXUr7$~%Sw_Kalv1k)0XaB>i2_$|HR*Nu&vKQS!eV0gI(H5VUXWSH~z za^hQ{Lly`$82>GwF!u~C!W`mK4W@*8<}i8dvM@OY5k`f%rifzYJnI8KhSE&?ItClY z2HD2r+`pgx<<>TR!PcP8@Ikim_P3^a4}7P}{J+TXhQlLvmE9`8sr8JL7!)`eh$Vu` sp2jz*FnBN#O-zaXDNeKnFZcgr6pyRCt6rSl2TYL+p00i_>zopr048=Q3;+NC literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/enderio/textures/gui/23/basic_item_filter.png b/src/main/resources/assets/enderio/textures/gui/23/basic_item_filter.png new file mode 100644 index 0000000000000000000000000000000000000000..7903e47fae73921120a864f6e87f2bfad72adee1 GIT binary patch literal 1923 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911MRQ8&P5Fo{p?&#~tz_78O`%fY(0|PTd zfKP}kP~62^QA&dRf`N&DBm;)v@9e6; zXy+{Oh%9DckUIdvjDmXGwgUy(OFVsD+3#~naT>~HYOjg|3Q3l@MwA5Sr&wt|zo%)NRtJ!w+>(>dzm;=@KY~^N}z{udB7q7^`kjD6@ z>dmyuZ%r;1DOn$S^_N zonad5j;H?@%?q7dqZ4=4rookof#E>JZUqKO28Jh}MCs2<5Odha_+`x-Yggm*^K54F zPIzx)sr6fE>MCKNPr#sIW0@m^5tLndUo)!INK)Z^>^U{N+b3;)Up$%9P;;qIt!~DA zYfxnZ2G9@yvuAu)S^g@;$YI{@IleX9CRcu2JozTW&n2?He+=x)f&PU6gKK&m4#3y| z0fYCRepgSXz`|z1e#TF4zUDmoeD};|`MGDeUl%V2byMpWkSf710bd%23ZrGQb( Oz~JfX=d#Wzp$Py(_(Nm> literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/enderio/textures/gui/23/big_item_filter.png b/src/main/resources/assets/enderio/textures/gui/23/big_item_filter.png new file mode 100644 index 0000000000000000000000000000000000000000..fb5917811579ae8cf883156ad990fed6903431ea GIT binary patch literal 1937 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911MRQ8&P5Fo{p?&#~tz_78O`%fY(0|PTd zfKP}kP~62^QA&dRf`N&DBm;)v@9e6; zXy+{Oh%9DcklP2sj1zbD)d2~HYOjg|3Q3l@MwA5SrXKF7bY-x_>wKu~e^ziaH=+@+EV-}P1>+dcQpRcGzH z43?SOrT9M=YeUok$>ZC&nI?eBVj%c(_escF6XqxPQm7xKZZFU<6_@Ff{C&J!jR_w1zvo*GRoDGYaQlTf+Qg$=xiQGw0VrQ~*hs+d%>s z$|nbJy~I;65y&pc*{#4J$-waBVK@hn3wB2#!xQTpp^v}snYp?>Y!~CF=;v#X#pleA zhPsb|!D3siKm!lRC7kGB`aOHKaB5z|oGsD4?LT*lLW~4@Dfu=l z;|VD5S6iw~seo zUn!Sx|I-Wakng|55A2Iwk+XBrsq|PQhMCFC6D-YWLpk669-q-Y_1v2LWD}6LJYD@< J);T3K0RXACNHYKc literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/enderio/textures/gui/23/filter_settings.png b/src/main/resources/assets/enderio/textures/gui/23/filter_settings.png new file mode 100644 index 0000000000000000000000000000000000000000..10e240d0f31871a36d1e051ac24907d84e5fec78 GIT binary patch literal 1961 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911MRQ8&P5Fo{p?&#~tz_78O`%fY(0|PTd zfKP}kP~62^QA&dRf`N&DBm;)v@9e6; zXy+{Oh%9DcklP2sj1zbD)d2iQi+}^ew{SIv%_cx*L$t37PzA?< zf2UXyrl|p$1*DNby=VA)pGDg!)t_18-p< zbH`N|po#{DH|yWLWvIJb{+;CZz z^8j}@=K&F*Ar*&}87m(CG-6zL|Nk*F3S*cif4mtR^^y;YP?3dNBAtFkuPt$bQ7Gvy}aO6wo@KhF$8Gkw87uesS(t|KTQI@s|r+ z?7crlkpnUrqSz260wV4n+#F_+p(DKDou}V5pq^BwJ*g01zL00Isg@PByPw)82eJg{ zr&}_j{~V&DA1=UZh!09|gnc(L2YJc*UweYGMZsnbySDz`VlX>FVdQ&MBb@0F5J7 AFaQ7m literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/enderio/textures/gui/23/filter_upgrade_settings.png b/src/main/resources/assets/enderio/textures/gui/23/filter_upgrade_settings.png new file mode 100644 index 0000000000000000000000000000000000000000..456cb9c658ea8b43053311e54e9f81af69e1aa4d GIT binary patch literal 10612 zcmeHtXH=6*+iqxr6cIrX1PP&+kU&C7=)L!<)DQxMP6)k7kq**(7o>==6%YYwHhS+U zSdb0^ZV^NTPSCyg>;B$vt+U>9&iCi6{j8NIGk3XW?rZLum6=SOzOEV#B?~100HD!O zS2hFyhzLa@00jx*%jLegF#vEG5@>9WH$?dXJ#iimSXT@XAK-}rV*IfV0D%9i+I*}j zTB<(k)P+He^vjUvWZf5s-Dn#d^&ZqoC(qSzNI`bP z+uW){F_4bg{`C7JY6~_=`$wA}o?F`3Sevoyfs=2m`Gux@_+pVfGc*8wWn2_h8IJ1= z9ksrx|2?4ba6mqrgBMmW%{(K&%+fpenZ%n$f21BSgph%h4t4W3I@*IK*eK+?L=D00f{VvHtiXG;b;;#zR4|F`=Ed^17spNQ%;z^iS4)ZlWWik6_at z4_pO3>@(H=EZDd8_?2zI^-oA!RW9N$nXx)vnYID!y~Rr~gmEO5?5&GRl!y%dvIN=a zE9iLQc(Ilx6H5My44go%@wYoT zeedZP++&-PaM>KzG0NI5t#dVU+!u^l&W#ojqhazHX#8lJ?|3W{fts3|qUaewZ3oU>M8uwwo9 zI(PHayzZT+Q%}Y)yQ(=SuCcI)Z$})%6dOA+lAKkY?2CydbsX9n9l};pWTGT`Uukd) z`*|F|sAr?4_IVjK{N}CPeJ0LcHOwf_KtMp|Sws(MX&DU(nZLSE_x)c#05t~?glB8fy{l$YCgs!@YzR0X} z`~}FLJc%|TF&ve@^u~hk0m@~S=mrOLn$JV;27^>OjVw`AK+}BoCM=xF`#zx3vf{m~ zZFF4Y4b$Rl)YnbT@((LJWn1UI0Yxef+}2g69q4;>8Q6_^YLwJZ^-sGSdfC~h0*K8W zSH!SnH-rMJDIaomAvHgGt*&L3;`7tXika^n$SaPYeiFfqN(eKbQ@=axpfhm!wJNI5 zpk=-3W9utxH%j-++hI`c9S06ZRlL9y31WP=p_^Fw6SH$oC>T4|bF3cOl~VLi;Wdhm&` zWgktB$hn4usynVqKzzt|4Hlc^WMsOik)BVqg>0LD@K;Y@wUN7{?n1ZaWO9JfYppjL z*xAY#19@#lXkR1x^K**q?U#!WWAg5JmoM;8czdP{w^2N?L0jQh~a)DBVg z8qP*4>|7u8QM9=m5kH!C9i;ood`G?RU&+ z1+V1F2Dk6C_b=Y1ob>2_*FssMQypW-=I%O0`!d)?EnszJtvrj`vV}*QdV0EjsUuhr z6z__?I`P?BQ7*de-KP2t4W7u1CykCzExJWSCSc~|#zDc>A?L=VWJSqp$!T)v1)c=X za~4CZ9(y?{sar$?sGVUi1 zje7grgXcNDA|JuZ;3C$OyTSRcgIjqT|;?r?l1SAizB#M@z;nWgQvf66@;j znQ4E6r1V+dS`YK+Z@CV^QAY`m!5Pe*(NcPn(Vy^JbBQ}oFN{#b*w z6r!9^`*OGv(#j~OifhT?PE3rZO31GMH^(c!hszrUn2l5pK6n%bUQ*sMeER{TIddE< z&Iq2I!^}Gt`ebX&{B6ixT8WXX>3WsKhM$eTn|n*$SpYYHh0Wky151Ik-y0`0=YqZxG`a83|KSgHCpo?CeN8&LUKUlVtyVtC$c)3SX} zF43(g{ry;6RGuXpAf-fptnQd|?&@wCbLb<(+MyD);i}ED5Qx78)KWsqqwPjQ_(I`!2NJb7D{edT03Nj zu9NcfL96Albx!BZ@`heiOToe6OQ!F)F2cD>8bRk-s}k$7S#a6`7k2}Q79}usvOoj%nnFI=`Ah2*!tdRfT6-FN!t5xlmF>l^s|LxTp#i@xE8J1-_WGvzIk}7xtZtW{=Tu|IR`Y|*7)7R!8)U2H)=2q zWy{5*+jAh%0JcL7#&jOeu2uf+sNr28;{HN8LQPPd58hRx>&80O$`QlsgQQ{SUHL|= zojVpiNRq>3+4@0yT}aZ1?fipd{${gOZkfICagNF^5FD35PruXvd{mJ85)Lz&N*A2a zTSdmXn0(n0;JpCZYoGI>3~%1?o@!Dc#UBWQAUsx+!eI`~%Z{|y>2V&{h*yiV|70de9(8Nmywmmb$*z-)Ku6t8EZyr0e zwB|PE*W%t~aMzlCERSa`41(*;@Z93xpBgCzNeB zd4)bnD02^3^YHZozH-(l$Gx+(g}wBb!*AqLa~sH`R<1o+$A04@a_LAoZ`F?|N|qGX$x_rn$+Pk3WOV6*!Q^YqX#a_+Z%Gc4HTIhb}X2{Yd9;kgS zvP6fmbsgBlfJ$r-G52|@Z>}BKH=Sp@UqFACD<4$8)4foWL9t7ysD0b12}2pGcA4o;Rc*SBd<@;!uv$CLZ{K>exQ7i9PxDw%pEEdll(~Tl zSG_lIq#wy?umWw=o+S!VZc;BZ8YKoogMr)N$c3t)V&I0DlHHR+=H*ja1>anMGVjWR z-jgL)Y}Ra0&yx_Ju+VM0ma`IIb+)Bugr(-xf;sMH68@bhH|%DBp#^n9yJV` zC3=+yxYYNQM_)@RTx3GMXRSW9`BvOprd9B)fC%~Q_*VImc%&FWq&FAIhiG-3fC;^^ z#+AHUw}W9w*J5N^^vvSZ9AB5@9EHC=p{J}Or?%wVjjMlL$+bh)@vZ&YO~~%l&Slv> z^`%FJIKc{diz^A6nb@;zB8ryz+52un^Ib(fShYEFM6e{ds|b|&oN>%>pesRYlXoQE zNMYVVYom>%n`y}xIFtZN+q71{r|^ibgkfZ*Q9_D@<$PcuDxC(4m$R)lgCtUEbQ7z0 zv990i(&i$!vtO#y(!&e-*X4Gn?nMkX26Ab7E7TDQu-gG&S~ZD�vT7vZ?o}ueW4T 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 MMOV2_(Kh0L0S5RyCIA2c literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/enderio/textures/gui/23/fluid_filter.png b/src/main/resources/assets/enderio/textures/gui/23/fluid_filter.png new file mode 100644 index 0000000000000000000000000000000000000000..7903e47fae73921120a864f6e87f2bfad72adee1 GIT binary patch literal 1923 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911MRQ8&P5Fo{p?&#~tz_78O`%fY(0|PTd zfKP}kP~62^QA&dRf`N&DBm;)v@9e6; zXy+{Oh%9DckUIdvjDmXGwgUy(OFVsD+3#~naT>~HYOjg|3Q3l@MwA5Sr&wt|zo%)NRtJ!w+>(>dzm;=@KY~^N}z{udB7q7^`kjD6@ z>dmyuZ%r;1DOn$S^_N zonad5j;H?@%?q7dqZ4=4rookof#E>JZUqKO28Jh}MCs2<5Odha_+`x-Yggm*^K54F zPIzx)sr6fE>MCKNPr#sIW0@m^5tLndUo)!INK)Z^>^U{N+b3;)Up$%9P;;qIt!~DA zYfxnZ2G9@yvuAu)S^g@;$YI{@IleX9CRcu2JozTW&n2?He+=x)f&PU6gKK&m4#3y| z0fYCRepgSXz`|z1e#TF4zUDmoeD};|`MGDeUl%V2byMpWkSf710bd%23ZrGQb( Oz~JfX=d#Wzp$Py(_(Nm> literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/enderio/textures/gui/23/in_out_settings.png b/src/main/resources/assets/enderio/textures/gui/23/in_out_settings.png new file mode 100644 index 0000000000000000000000000000000000000000..dc331367bb232ad7ca357de7ea7e107021707223 GIT binary patch literal 10069 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/enderio/textures/gui/23/item_filter.png b/src/main/resources/assets/enderio/textures/gui/23/item_filter.png new file mode 100644 index 0000000000000000000000000000000000000000..21535202ac00d1c0826b41ccbeb866a23d59256b GIT binary patch literal 1883 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911MRQ8&P5Fo{p?&#~tz_78O`%fY(0|PTd zfKP}kP~62^QA&dRf`N&DBm;)v@9e6; zXy+{Oh%9DckUIdvjDmXGwgUy(OFVsD+3#~naT>~HYOjg|3Q3l@MwA5Sr%*e07GUORsEm z;rjsJ_qX)bR~XFIxx@11QttijyT7^R{{B`NuHN{z{r&&PdoQ*>;QCN^`?hq$pO63L z8`v3^>y_)j6m+PQnYY=iQI%1v-rJVxMELVHpVCEuPGWd+Lm5P_E@oq3Xo&g${`R-G zpZDyxVtf<5@1?!f_wVt%AAX*Hu@wqh{}}B5#sbrm5VKo>K@!4CxHo&wD)q^XpYA=)c(i-&n~TBzY0OV1f4h2w|8urK zOb5fUt=vo#K=lj|JllJ6WtEX+!bBk3U|sBm@`gRtwzGcJnOA?gGWjOM&)m;fkHlxJ zw}mQ)hdEgDjPGXKU!6>8aAjgxV1D2>OGE8$x!rzW8GcV&JblHx-}VgOau*go?b13Q zWyElE8{>&>ybjxP88+oIPso*S$hpmsa+^)zwi$&|nZN%@3oShyw|Bwi9UxbEy85}S Ib4q9e0Py`X-T(jq literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/enderio/textures/gui/23/mod_item_filter.png b/src/main/resources/assets/enderio/textures/gui/23/mod_item_filter.png new file mode 100644 index 0000000000000000000000000000000000000000..f50d9568ecb10975dc2d2254661e1b9c4e2c0ae6 GIT binary patch literal 1975 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911MRQ8&P5Fo{p?&#~tz_78O`%fY(0|PTd zfKP}kP~62^QA&dRf`N&DBm;)v@9e6; zXy+{Oh%9DcklPEwj5f^cg@J+fCio2(CfPmYgg+VJPU`T_2S zmC5fF_cA>={cw&e*Bl{*PrI*ZGuX}Ad}4hd6Nf?r!<}vF4Gc^lF3#Zua&rE^*Y@6d zH$PmhVd;lO^`_rn_p|NzYh2O8em2VFK&{PBFN1ubE{EG?4on6t0u8h0D>AYOEXcK1 zV3c6uIB@p-1O_IK3)^HTFz_(4Jb1SKpG{d}qHy-{Yh^|<4?bPETz>rB=DrngT^JZy zGH&yEFtjl+U5UQV@*p#tX~PCj1~Go$hF=+Q6ZbRf{dvAdj(hgE`K2yjFD_M zLXts!gROsS0R{5|*BKg?-pQ|?_lR-Yp|$>jcV53| x@U{%hv0QYbdae=Uj7;H%nP#-1Jfo+{*G*rx?gR6)*}$B`;OXk;vd$@?2>`|H(?D8gCb z5n0T@Aa@Xi84qWM1Oo-xOFVsD*&i`6va0dEYmkg%U|{~~>EaktaqI1!z^+>XA`K6V zk4`NS?A0g{zE>*3<|KYmTzrznX#`<42(8JB)12U%p+`v?kd zT>HzeVe_}+Q~c`hg{8_&fBN#n_jC3fILPm2K7vWyNG&5o{KzZ`s3--)Gs}A zinruu_gRLYznNp^_fwatU>9TZl~UQ<+q06-T`k_VuK1KK69W?i2ZI6->M?@o1_r1A zoN+*TR<69mIm=hO%#P2QeJ(Mgt7G5$-yI#E)75Wqq@1%oGqXtfLf-c7j*exSe(A^c z8`kF?kTAP9!?>)k*Wn%`+&H*_s0BcjfReXnYSd5OlE#SV%QF4@5;_xx);$!DF z3ZAe=L>%@wY+z4So?z*EKJiA5bmIaO)jXC@91LJ7(4MO{6 z3Jxk`4PbPe(IeqZ(o3N`$KKDs?|%M-~4WOA*)tpO{zZwOa;aU&p$t#x6+L1?AMbV1Ru5UkT&$#3H`Qybb2V&dR)$lw0z}{%Ttuv3!*<>ew{vp54JI>AgTe~DWM4fioLmb?$xbr@Z&1n!m`&{rmiD-*)ZqzZkAq z?%%sNwruU^r`Oj0H#~5^nz!~xeN|;;W!?VDU*!ji=G*THfB*93%ja?|3|brvHOWj2 z_iv;yoJ;%v*&;)WVdZ`8L-&Om^?!W*!qQOokE`^~^LBAwhez{f-gi7J#ISod=Yc|| zgmPm>3qOW8d1?&DIUDYtWqDx1xMBB91{rmRGIQaE$1Dflr7;!EVYqSEhoMgxS<}1g z(v2(!ZmBcG7uVHS*xSj)CGj&QFasE;>%FP;=u4qjlq&hfuU5mL55Uq zK&Kq%zrQu_@8P1;m2FHL=9)9{o--C{cw56N!Pk(k!7!VX8rBeY-AA_t2S*(+C_>=w zP5zl%K`HA1IAJ9K)76}h)0=iZ_WRYkf@y;Bzi@`~JD&epT|i3aUM*)yn8vVU^RGUJ zGeQjIVfO_aBAFhXdu7dJ;LUI+veum;jkCde^?Qy3I*bMBUu79*s4~1;vrm~}Gg+EV z{{;n<-`Uy5aORVn0>rj`Omwpy-Rb5`JHZ|wOm4CI|I%@G?i^47aTPTdW%60ez%lUj zd;mdKI;Vst0PV(!g#Z8m literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/enderio/textures/gui/23/soul_filter_normal.png b/src/main/resources/assets/enderio/textures/gui/23/soul_filter_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..140e218a49d9e740cb23f9a1df1d8ead98d9b7a8 GIT binary patch literal 1690 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