diff --git a/src/main/java/codechicken/nei/BookmarkPanel.java b/src/main/java/codechicken/nei/BookmarkPanel.java index ac300bb5..ceadf0a1 100644 --- a/src/main/java/codechicken/nei/BookmarkPanel.java +++ b/src/main/java/codechicken/nei/BookmarkPanel.java @@ -1053,7 +1053,7 @@ public class BookmarkPanel extends PanelWidget { if (NEIClientUtils.altKey()) { multiplier = NEIClientConfig.showItemQuantityWidget() ? NEIClientConfig.getItemQuantity() : 0; if (multiplier == 0) { - multiplier = StackInfo.itemStackToNBT(slot.getItemStack()).hasKey("gtFluidName") ? 144 + multiplier = StackInfo.isFluidDisplayItem(slot.getItemStack()) ? 144 : slot.getItemStack().getMaxStackSize(); } } diff --git a/src/main/java/codechicken/nei/ItemCraftablesPanel.java b/src/main/java/codechicken/nei/ItemCraftablesPanel.java index 30b7dec1..af2627ff 100644 --- a/src/main/java/codechicken/nei/ItemCraftablesPanel.java +++ b/src/main/java/codechicken/nei/ItemCraftablesPanel.java @@ -39,7 +39,7 @@ public class ItemCraftablesPanel public CraftablesGridSlot(int slotIndex, int itemIndex, ItemStack itemStack, RecipeId recipeId) { super(slotIndex, itemIndex, itemStack); this.realAmount = StackInfo.getAmount(itemStack); - this.isFluidDisplay = StackInfo.itemStackToNBT(itemStack).hasKey("gtFluidName"); + this.isFluidDisplay = StackInfo.isFluidDisplayItem(itemStack); this.recipeId = recipeId; } diff --git a/src/main/java/codechicken/nei/ItemQuantityField.java b/src/main/java/codechicken/nei/ItemQuantityField.java index 8189597d..1b9d6cec 100644 --- a/src/main/java/codechicken/nei/ItemQuantityField.java +++ b/src/main/java/codechicken/nei/ItemQuantityField.java @@ -86,7 +86,7 @@ public class ItemQuantityField extends TextField { amount = NEIClientConfig.showItemQuantityWidget() ? NEIClientConfig.getItemQuantity() : 0; if (amount == 0) { - amount = StackInfo.itemStackToNBT(stack).hasKey("gtFluidName") ? 144 : stack.getMaxStackSize(); + amount = StackInfo.isFluidDisplayItem(stack) ? 144 : stack.getMaxStackSize(); } } diff --git a/src/main/java/codechicken/nei/ItemsTooltipLineHandler.java b/src/main/java/codechicken/nei/ItemsTooltipLineHandler.java index cf5625aa..bc64bdef 100644 --- a/src/main/java/codechicken/nei/ItemsTooltipLineHandler.java +++ b/src/main/java/codechicken/nei/ItemsTooltipLineHandler.java @@ -163,9 +163,10 @@ public class ItemsTooltipLineHandler implements ITooltipLineHandler { for (Map.Entry entry : ItemStackAmount.of(items).entrySet()) { final ItemStack stack = StackInfo.loadFromNBT(entry.getKey(), Math.max(0, entry.getValue())); - if (entry.getKey().hasKey("gtFluidName")) { + if (stack != null && StackInfo.isFluidDisplayItem(stack)) { stack.stackSize = 0; } + result.add(stack); } diff --git a/src/main/java/codechicken/nei/LayoutManager.java b/src/main/java/codechicken/nei/LayoutManager.java index 2eb45230..bb10c9d6 100644 --- a/src/main/java/codechicken/nei/LayoutManager.java +++ b/src/main/java/codechicken/nei/LayoutManager.java @@ -119,11 +119,6 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH */ public static boolean itemsLoaded = false; - /** - * Not present, Present - */ - public static Image[] itemPresenceOverlays = new Image[2]; - public static void load() { API.addLayoutStyle(0, new LayoutStyleMinecraft()); @@ -939,17 +934,6 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH tessellator.addVertexWithUV(x, y, z, u, v); } - public static void drawItemPresenceOverlay(int slotX, int slotY, boolean isPresent, boolean slotHighlight) { - - if (slotHighlight) { - NEIClientUtils.gl2DRenderContext(() -> drawRect(slotX, slotY, 16, 16, isPresent ? 0x8000AA00 : 0x80AA0000)); - } else { - Image icon = itemPresenceOverlays[isPresent ? 1 : 0]; - drawIcon(slotX + 16 - icon.width, slotY + 16 - icon.height, icon); - } - - } - public static LayoutManager instance() { return instance; } diff --git a/src/main/java/codechicken/nei/LayoutStyleMinecraft.java b/src/main/java/codechicken/nei/LayoutStyleMinecraft.java index 7d8bda93..14cc9cf8 100644 --- a/src/main/java/codechicken/nei/LayoutStyleMinecraft.java +++ b/src/main/java/codechicken/nei/LayoutStyleMinecraft.java @@ -8,7 +8,6 @@ import org.lwjgl.opengl.GL11; import codechicken.lib.vec.Rectangle4i; import codechicken.nei.api.LayoutStyle; -import codechicken.nei.drawable.DrawableBuilder; public class LayoutStyleMinecraft extends LayoutStyle { @@ -38,10 +37,6 @@ public class LayoutStyleMinecraft extends LayoutStyle { LayoutManager.timeButtons[2].icon = new Image(144, 24, 12, 12); LayoutManager.timeButtons[3].icon = new Image(156, 24, 12, 12); LayoutManager.heal.icon = new Image(168, 24, 12, 12); - LayoutManager.itemPresenceOverlays[0] = new DrawableBuilder("nei:textures/nei_tabbed_sprites.png", 0, 40, 8, 8) - .build(); - LayoutManager.itemPresenceOverlays[1] = new DrawableBuilder("nei:textures/nei_tabbed_sprites.png", 8, 40, 8, 8) - .build(); } @Override diff --git a/src/main/java/codechicken/nei/NEIClientConfig.java b/src/main/java/codechicken/nei/NEIClientConfig.java index ef3a68b3..2feb7266 100644 --- a/src/main/java/codechicken/nei/NEIClientConfig.java +++ b/src/main/java/codechicken/nei/NEIClientConfig.java @@ -387,6 +387,13 @@ public class NEIClientConfig { setFavoriteDefaults(tag); + tag.getTag("inventory.tooltip.showFluidTemperature").setComment("Enabled show Fluid Temperature") + .getBooleanValue(true); + API.addOption(new OptionToggleButton("inventory.tooltip.showFluidTemperature", true)); + + tag.getTag("inventory.tooltip.showFluidState").setComment("Enabled show Fluid State").getBooleanValue(true); + API.addOption(new OptionToggleButton("inventory.tooltip.showFluidState", true)); + tag.getTag("inventory.itemIDs").getIntValue(1); API.addOption(new OptionCycled("inventory.itemIDs", 3, true)); diff --git a/src/main/java/codechicken/nei/NEIClientUtils.java b/src/main/java/codechicken/nei/NEIClientUtils.java index 8a3caed3..a1cd5282 100644 --- a/src/main/java/codechicken/nei/NEIClientUtils.java +++ b/src/main/java/codechicken/nei/NEIClientUtils.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.IdentityHashMap; import java.util.LinkedList; import java.util.List; import java.util.Locale; @@ -41,6 +42,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.IChatComponent; import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fluids.FluidStack; import org.lwjgl.input.Keyboard; import org.lwjgl.opengl.GL11; @@ -56,6 +58,8 @@ import codechicken.lib.vec.Rectangle4i; import codechicken.nei.api.GuiInfo; import codechicken.nei.api.IInfiniteItemHandler; import codechicken.nei.api.ItemInfo; +import codechicken.nei.recipe.GuiOverlayButton.ItemOverlayState; +import codechicken.nei.recipe.StackInfo; import codechicken.nei.util.NEIKeyboardUtils; public class NEIClientUtils extends NEIServerUtils { @@ -293,6 +297,83 @@ public class NEIClientUtils extends NEIServerUtils { return InventoryUtils.getInsertibleQuantity(new InventoryRange(player.inventory, 0, 36), itemstack) > 0; } + public static List presenceOverlay(List ingredients, List invStacks) { + final List states = new ArrayList<>(); + final Map remainingFluid = new IdentityHashMap<>(); + + for (PositionedStack stack : ingredients) { + boolean found; + + if (StackInfo.isFluidDisplayItem(stack.item)) { + final FluidStack requiredFluid = StackInfo.getFluid(stack.item); + found = requiredFluid != null && consumeFluid(invStacks, remainingFluid, requiredFluid); + } else { + found = false; + + for (ItemStack is : invStacks) { + if (is.stackSize > 0 && stack.contains(is)) { + is.stackSize--; + found = true; + break; + } + } + } + + states.add(new ItemOverlayState(stack, found)); + } + + return states; + } + + private static boolean consumeFluid(List invStacks, Map remainingFluid, + FluidStack requiredFluid) { + long need = requiredFluid.amount; + final List matched = new ArrayList<>(); + + for (ItemStack is : invStacks) { + if (need <= 0) { + break; + } + + if (is.stackSize <= 0) { + continue; + } + + final FluidStack invFluid = StackInfo.getFluid(is); + + if (invFluid == null || !invFluid.isFluidEqual(requiredFluid)) { + continue; + } + + final long available = remainingFluid.computeIfAbsent(is, k -> (long) invFluid.amount * is.stackSize); + if (available <= 0) { + continue; + } + + matched.add(is); + need -= available; + } + + if (need > 0) { + return false; + } + + long remainingNeed = requiredFluid.amount; + for (ItemStack is : matched) { + final long available = remainingFluid.get(is); + final long consumed = Math.min(available, remainingNeed); + + remainingFluid.put(is, available - consumed); + remainingNeed -= consumed; + + if (remainingNeed <= 0) { + break; + } + } + + return true; + } + public static boolean shiftKey() { return Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT); } diff --git a/src/main/java/codechicken/nei/NEIServerUtils.java b/src/main/java/codechicken/nei/NEIServerUtils.java index d3dfd5b5..336230fa 100644 --- a/src/main/java/codechicken/nei/NEIServerUtils.java +++ b/src/main/java/codechicken/nei/NEIServerUtils.java @@ -35,6 +35,7 @@ import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.IChatComponent; import net.minecraft.world.World; import net.minecraft.world.WorldSettings.GameType; +import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.oredict.OreDictionary; import org.apache.logging.log4j.Level; @@ -45,6 +46,7 @@ import codechicken.lib.inventory.InventoryRange; import codechicken.lib.inventory.InventoryUtils; import codechicken.lib.packet.PacketCustom; import codechicken.nei.PacketIDs.S2C; +import codechicken.nei.item.ItemFluidDisplay; import codechicken.nei.recipe.StackInfo; import codechicken.nei.util.NBTHelper; import cpw.mods.fml.common.FMLLog; @@ -442,13 +444,49 @@ public class NEIServerUtils { throw new RuntimeException(msg); } - @SuppressWarnings("unchecked") public static ItemStack[] extractRecipeItems(Object obj) { - if (obj instanceof ItemStack) return new ItemStack[] { (ItemStack) obj }; - if (obj instanceof ItemStack[]) return (ItemStack[]) obj; - if (obj instanceof List) return ((List) obj).toArray(new ItemStack[0]); - throw new ClassCastException(obj + " not an ItemStack, ItemStack[] or List getRange(final int start, final int end) { diff --git a/src/main/java/codechicken/nei/PositionedStack.java b/src/main/java/codechicken/nei/PositionedStack.java index a203ad42..c892b424 100644 --- a/src/main/java/codechicken/nei/PositionedStack.java +++ b/src/main/java/codechicken/nei/PositionedStack.java @@ -6,11 +6,19 @@ import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.init.Blocks; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IIcon; +import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.oredict.OreDictionary; +import org.lwjgl.opengl.GL11; + import codechicken.nei.api.ItemFilter; import codechicken.nei.api.ItemInfo; import codechicken.nei.guihook.GuiContainerManager; @@ -230,9 +238,6 @@ public class PositionedStack implements Cloneable { return "PositionedStack(output='" + item.toString() + "')"; } - /** - * A {@link PositionedStack} that keeps its items but never draws them. - */ public static class Placeholder extends PositionedStack { public Placeholder(Object object, int x, int y, boolean genPerms) { @@ -246,4 +251,124 @@ public class PositionedStack implements Cloneable { @Override public void draw(int mousex, int mousey) {} } + + public static class Fluid extends PositionedStack { + + /** The tank size the fill level is measured against, in mB. 0 means "always render full". */ + public int capacity = 0; + + private ItemStack cachedFluidItem; + private FluidStack cachedFluidStack; + + public Fluid(Object object, int x, int y, boolean genPerms) { + super(object, x, y, genPerms); + } + + public Fluid(Object object, int x, int y) { + this(object, x, y, true); + } + + public Fluid(Object object, int x, int y, int width, int height, int capacity) { + super(object, x, y, false); + this.width = width; + this.height = height; + this.capacity = capacity; + } + + protected FluidStack getFluidStack() { + + if (this.item != this.cachedFluidItem) { + this.cachedFluidItem = this.item; + this.cachedFluidStack = StackInfo.isFluidDisplayItem(this.item) ? StackInfo.getFluid(this.item) : null; + } + + return this.cachedFluidStack; + } + + @Override + public List getTooltip() { + final List tooltip = new ArrayList<>(); + final List customTooltip = super.getTooltip(); + final FluidStack fluidStack = getFluidStack(); + + if (fluidStack != null) { + tooltip.add( + EnumChatFormatting.GRAY + NEIClientUtils + .translate("recipe.fluid.tank.amount", NEIClientUtils.formatFluid(fluidStack.amount))); + } + + if (customTooltip != null) { + tooltip.addAll(customTooltip); + } + + return tooltip; + } + + @Override + public void draw(int mousex, int mousey) { + final FluidStack fluidStack = getFluidStack(); + + if (fluidStack == null) { + super.draw(mousex, mousey); + return; + } + + final int tankCapacity = this.capacity > 0 ? this.capacity : fluidStack.amount; + int fillHeight = tankCapacity > 0 + ? (int) ((long) this.height * Math.min(fluidStack.amount, tankCapacity) / tankCapacity) + : 0; + + if (fluidStack.amount > 0 && fillHeight <= 0) { + fillHeight = 1; + } + + if (fillHeight > 0) { + drawFluid(this.relx, this.rely, this.width, this.height, fillHeight, fluidStack); + } + } + + private static void drawFluid(int x, int y, int width, int height, int fillHeight, FluidStack fluidStack) { + final IIcon icon = fluidStack.getFluid().getIcon(fluidStack); + + if (icon == null) { + return; + } + + final int color = fluidStack.getFluid().getColor(fluidStack); + final float red = (color >> 16 & 0xFF) / 255F; + final float green = (color >> 8 & 0xFF) / 255F; + final float blue = (color & 0xFF) / 255F; + + Minecraft.getMinecraft().getTextureManager().bindTexture(TextureMap.locationBlocksTexture); + GL11.glColor4f(red, green, blue, 1F); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glDisable(GL11.GL_LIGHTING); + + final Tessellator tessellator = Tessellator.instance; + + tessellator.startDrawingQuads(); + for (int tx = 0; tx < width; tx += 16) { + final int tileWidth = Math.min(16, width - tx); + final double u2 = icon.getMinU() + (icon.getMaxU() - icon.getMinU()) * tileWidth / 16D; + + for (int ty = 0; ty < fillHeight; ty += 16) { + final int tileHeight = Math.min(16, fillHeight - ty); + final double v2 = icon.getMinV() + (icon.getMaxV() - icon.getMinV()) * tileHeight / 16D; + final int bottomY = y + height - ty; + final int topY = bottomY - tileHeight; + + tessellator.addVertexWithUV(x + tx, bottomY, 0, icon.getMinU(), v2); + tessellator.addVertexWithUV(x + tx + tileWidth, bottomY, 0, u2, v2); + tessellator.addVertexWithUV(x + tx + tileWidth, topY, 0, u2, icon.getMinV()); + tessellator.addVertexWithUV(x + tx, topY, 0, icon.getMinU(), icon.getMinV()); + } + } + tessellator.draw(); + + GL11.glDisable(GL11.GL_BLEND); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glColor4f(1F, 1F, 1F, 1F); + } + } } diff --git a/src/main/java/codechicken/nei/api/IOverlayHandler.java b/src/main/java/codechicken/nei/api/IOverlayHandler.java index 08f1d72b..c49c218f 100644 --- a/src/main/java/codechicken/nei/api/IOverlayHandler.java +++ b/src/main/java/codechicken/nei/api/IOverlayHandler.java @@ -1,15 +1,12 @@ package codechicken.nei.api; -import java.util.ArrayList; import java.util.List; -import java.util.Optional; import java.util.stream.Collectors; import net.minecraft.client.gui.inventory.GuiContainer; -import net.minecraft.item.ItemStack; import codechicken.nei.NEIClientConfig; -import codechicken.nei.PositionedStack; +import codechicken.nei.NEIClientUtils; import codechicken.nei.recipe.GuiOverlayButton.ItemOverlayState; import codechicken.nei.recipe.IRecipeHandler; @@ -38,28 +35,14 @@ public interface IOverlayHandler { } default List presenceOverlay(GuiContainer firstGui, IRecipeHandler recipe, int recipeIndex) { - final List itemPresenceSlots = new ArrayList<>(); - final List ingredients = recipe.getIngredientStacks(recipeIndex); - final List invStacks = firstGui.inventorySlots.inventorySlots.stream() - .filter( - s -> s != null && s.getStack() != null - && s.getStack().stackSize > 0 - && s.isItemValid(s.getStack()) - && s.canTakeStack(firstGui.mc.thePlayer)) - .map(s -> s.getStack().copy()).collect(Collectors.toList()); - - for (PositionedStack stack : ingredients) { - Optional used = invStacks.stream().filter(is -> is.stackSize > 0 && stack.contains(is)) - .findAny(); - - itemPresenceSlots.add(new ItemOverlayState(stack, used.isPresent())); - - if (used.isPresent()) { - ItemStack is = used.get(); - is.stackSize -= 1; - } - } - - return itemPresenceSlots; + return NEIClientUtils.presenceOverlay( + recipe.getIngredientStacks(recipeIndex), + firstGui.inventorySlots.inventorySlots.stream() + .filter( + s -> s != null && s.getStack() != null + && s.getStack().stackSize > 0 + && s.isItemValid(s.getStack()) + && s.canTakeStack(firstGui.mc.thePlayer)) + .map(s -> s.getStack().copy()).collect(Collectors.toList())); } } diff --git a/src/main/java/codechicken/nei/api/IStackStringifyHandler.java b/src/main/java/codechicken/nei/api/IStackStringifyHandler.java index 27586f36..705b6384 100644 --- a/src/main/java/codechicken/nei/api/IStackStringifyHandler.java +++ b/src/main/java/codechicken/nei/api/IStackStringifyHandler.java @@ -24,4 +24,8 @@ public interface IStackStringifyHandler { default void pauseItemDamageSound(boolean pause) {} + default boolean isFluidDisplayItem(ItemStack stack) { + return false; + } + } diff --git a/src/main/java/codechicken/nei/api/ItemInfo.java b/src/main/java/codechicken/nei/api/ItemInfo.java index 00fc2d8a..623499c0 100644 --- a/src/main/java/codechicken/nei/api/ItemInfo.java +++ b/src/main/java/codechicken/nei/api/ItemInfo.java @@ -60,6 +60,7 @@ import codechicken.nei.config.HandlerDumper; import codechicken.nei.config.ItemPanelDumper; import codechicken.nei.config.RegistryDumper; import codechicken.nei.guihook.GuiContainerManager; +import codechicken.nei.item.ItemFluidDisplay; import codechicken.nei.recipe.BrewingRecipeHandler; import codechicken.nei.recipe.RecipeItemInputHandler; import codechicken.nei.search.IdentifierFilter; @@ -133,6 +134,7 @@ public class ItemInfo { public static void preInit() { addMobSpawnerItem(); + addFluidDisplayItem(); } public static void load() { @@ -318,6 +320,10 @@ public class ItemInfo { GameDataManipulator.replaceItem(Block.getIdFromBlock(Blocks.mob_spawner), new ItemMobSpawner()); } + private static void addFluidDisplayItem() { + GameRegistry.registerItem(new ItemFluidDisplay(), "neiFluidDisplay"); + } + private static void addInfiniteHandlers() { API.addInfiniteItemHandler(new InfiniteStackSizeHandler()); API.addInfiniteItemHandler(new InfiniteToolHandler()); @@ -402,6 +408,7 @@ public class ItemInfo { item -> item.getItem() instanceof ItemArmor armor && armor.armorType == 2); API.addSubset("Items.Armor.Boots", item -> item.getItem() instanceof ItemArmor armor && armor.armorType == 3); API.addSubset("Items.Food", item -> item.getItem() instanceof ItemFood); + API.addSubset("Items.Fluids", item -> item.getItem() instanceof ItemFluidDisplay); API.addSubset("Items.Potions.Ingredients", BrewingRecipeHandler.ingredients); for (CreativeTabs tab : CreativeTabs.creativeTabArray) { diff --git a/src/main/java/codechicken/nei/bookmark/BookmarkGrid.java b/src/main/java/codechicken/nei/bookmark/BookmarkGrid.java index 95958a47..cf52df15 100644 --- a/src/main/java/codechicken/nei/bookmark/BookmarkGrid.java +++ b/src/main/java/codechicken/nei/bookmark/BookmarkGrid.java @@ -24,7 +24,7 @@ import codechicken.lib.gui.GuiDraw; import codechicken.lib.vec.Rectangle4i; import codechicken.nei.BookmarkPanel.BookmarkViewMode; import codechicken.nei.ItemPanels; -import codechicken.nei.ItemStackSet; +import codechicken.nei.ItemStackAmount; import codechicken.nei.ItemsGrid; import codechicken.nei.ItemsGrid.MouseContext; import codechicken.nei.LayoutManager; @@ -913,8 +913,8 @@ public class BookmarkGrid extends ItemsGrid results = new ArrayList<>(); final List ingredients = new ArrayList<>(); diff --git a/src/main/java/codechicken/nei/bookmark/BookmarkItem.java b/src/main/java/codechicken/nei/bookmark/BookmarkItem.java index 6e2ae404..2c54f938 100644 --- a/src/main/java/codechicken/nei/bookmark/BookmarkItem.java +++ b/src/main/java/codechicken/nei/bookmark/BookmarkItem.java @@ -42,7 +42,7 @@ public class BookmarkItem { this.groupId = groupId; this.stack = stack; - this.factor = nbTag.hasKey("gtFluidName") ? Math.min(144, nbTag.getInteger("Count")) : 1; + this.factor = StackInfo.isFluidDisplayItem(stack) ? Math.min(144, nbTag.getInteger("Count")) : 1; } public Builder factor(long factor) { diff --git a/src/main/java/codechicken/nei/bookmark/BookmarksGridSlot.java b/src/main/java/codechicken/nei/bookmark/BookmarksGridSlot.java index 5bbede47..d9c8d5de 100644 --- a/src/main/java/codechicken/nei/bookmark/BookmarksGridSlot.java +++ b/src/main/java/codechicken/nei/bookmark/BookmarksGridSlot.java @@ -82,7 +82,7 @@ public class BookmarksGridSlot extends ItemsGridSlot { this.bookmarkItem = bookmarkItem; this.isOutputRecipe = group.crafting != null && group.crafting.outputRecipes.contains(bookmarkItem.recipeId); - this.isFluidDisplay = StackInfo.itemStackToNBT(bookmarkItem.itemStack).hasKey("gtFluidName"); + this.isFluidDisplay = StackInfo.isFluidDisplayItem(bookmarkItem.itemStack); this.realMultiplier = realMultiplier; this.calculatedMultiplier = calculatedMultiplier; diff --git a/src/main/java/codechicken/nei/item/FluidDisplayRenderer.java b/src/main/java/codechicken/nei/item/FluidDisplayRenderer.java new file mode 100644 index 00000000..1518a975 --- /dev/null +++ b/src/main/java/codechicken/nei/item/FluidDisplayRenderer.java @@ -0,0 +1,92 @@ +package codechicken.nei.item; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraftforge.client.IItemRenderer; +import net.minecraftforge.fluids.FluidStack; + +import org.lwjgl.opengl.GL11; + +import codechicken.nei.util.ReadableNumberConverter; + +public class FluidDisplayRenderer implements IItemRenderer { + + @Override + public boolean handleRenderType(ItemStack item, ItemRenderType type) { + return type == ItemRenderType.INVENTORY; + } + + @Override + public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) { + return false; + } + + @Override + public void renderItem(ItemRenderType type, ItemStack item, Object... data) { + if (type != ItemRenderType.INVENTORY || !(item.getItem() instanceof ItemFluidDisplay fluidDisplay)) { + return; + } + + renderIcon(item, fluidDisplay); + renderAmountOverlay(item, fluidDisplay); + } + + private void renderIcon(ItemStack item, ItemFluidDisplay fluidDisplay) { + final IIcon icon = fluidDisplay.getIconIndex(item); + if (icon == null) { + return; + } + + final int color = fluidDisplay.getColorFromItemStack(item, 0); + final float red = (color >> 16 & 0xFF) / 255F; + final float green = (color >> 8 & 0xFF) / 255F; + final float blue = (color & 0xFF) / 255F; + + Minecraft.getMinecraft().getTextureManager().bindTexture(TextureMap.locationBlocksTexture); + GL11.glColor4f(red, green, blue, 1F); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + + final Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(0, 16, 0, icon.getMinU(), icon.getMaxV()); + tessellator.addVertexWithUV(16, 16, 0, icon.getMaxU(), icon.getMaxV()); + tessellator.addVertexWithUV(16, 0, 0, icon.getMaxU(), icon.getMinV()); + tessellator.addVertexWithUV(0, 0, 0, icon.getMinU(), icon.getMinV()); + tessellator.draw(); + + GL11.glColor4f(1F, 1F, 1F, 1F); + GL11.glDisable(GL11.GL_BLEND); + } + + private void renderAmountOverlay(ItemStack item, ItemFluidDisplay fluidDisplay) { + final FluidStack fluidStack = fluidDisplay.getFluid(item); + if (fluidStack == null || fluidStack.amount <= 0) { + return; + } + + String amountString = ""; + + if (fluidStack.amount < 10_000) { + amountString = String.valueOf(fluidStack.amount) + "L"; + } else { + amountString = ReadableNumberConverter.INSTANCE.toWideReadableForm(fluidStack.amount) + "L"; + } + + final FontRenderer fontRender = Minecraft.getMinecraft().fontRenderer; + float smallTextScale = fontRender.getUnicodeFlag() ? 3F / 4F : 1F / 2F; + GL11.glPushAttrib(GL11.GL_ENABLE_BIT); + GL11.glDisable(GL11.GL_BLEND); + GL11.glPushMatrix(); + GL11.glScalef(smallTextScale, smallTextScale, 1.0f); + + fontRender + .drawString(amountString, 0, (int) (16 / smallTextScale) - fontRender.FONT_HEIGHT + 1, 0xFFFFFF, true); + GL11.glPopMatrix(); + GL11.glPopAttrib(); + } +} diff --git a/src/main/java/codechicken/nei/item/ItemFluidDisplay.java b/src/main/java/codechicken/nei/item/ItemFluidDisplay.java new file mode 100644 index 00000000..fd5e8fc2 --- /dev/null +++ b/src/main/java/codechicken/nei/item/ItemFluidDisplay.java @@ -0,0 +1,196 @@ +package codechicken.nei.item; + +import java.util.List; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IIcon; +import net.minecraftforge.client.MinecraftForgeClient; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidContainerItem; + +import codechicken.nei.NEIClientConfig; +import codechicken.nei.NEIClientUtils; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +public class ItemFluidDisplay extends Item implements IFluidContainerItem { + + public static ItemFluidDisplay INSTANCE; + + public final static CreativeTabs tabFluids = new CreativeTabs("neiFluids") { + + @Override + public Item getTabIconItem() { + return INSTANCE; + } + + @Override + @SideOnly(Side.CLIENT) + public ItemStack getIconItemStack() { + return createStack(new FluidStack(FluidRegistry.WATER, 0)); + } + }; + + public ItemFluidDisplay() { + setMaxStackSize(1); + setUnlocalizedName("nei.fluidDisplay"); + INSTANCE = this; + + setCreativeTab(tabFluids); + MinecraftForgeClient.registerItemRenderer(this, new FluidDisplayRenderer()); + } + + public static ItemStack createStack(FluidStack fluidStack) { + if (fluidStack == null || fluidStack.getFluid() == null) { + return null; + } + + int fluidId; + + try { + fluidId = FluidRegistry.getFluidID(fluidStack.getFluid()); + } catch (Exception e) { + NEIClientConfig.logger.error("Failed to get fluid id for: " + fluidStack.getFluid().getName(), e); + return null; + } + + final ItemStack stack = new ItemStack(INSTANCE, 1, fluidId); + final NBTTagCompound nbtTag = new NBTTagCompound(); + + if (fluidStack.tag != null) { + nbtTag.setTag("FluidTag", fluidStack.tag.copy()); + } + + nbtTag.setInteger("neiFluidDisplayAmount", fluidStack.amount); + stack.setTagCompound(nbtTag); + return stack; + } + + @Override + public FluidStack getFluid(ItemStack stack) { + + if (stack == null || !(stack.getItem() instanceof ItemFluidDisplay) || !stack.hasTagCompound()) { + return null; + } + + final Fluid fluid = FluidRegistry.getFluid(stack.getItemDamage()); + + if (fluid == null) { + return null; + } + + final NBTTagCompound nbTag = stack.getTagCompound(); + final FluidStack fluidStack = new FluidStack(fluid, nbTag.getInteger("neiFluidDisplayAmount")); + + if (nbTag.hasKey("FluidTag")) { + fluidStack.tag = nbTag.getCompoundTag("FluidTag"); + } + + return fluidStack; + } + + @Override + public int getCapacity(ItemStack stack) { + + if (stack == null || !(stack.getItem() instanceof ItemFluidDisplay) || !stack.hasTagCompound()) { + return 0; + } + + return stack.getTagCompound().getInteger("neiFluidDisplayAmount"); + } + + @Override + public int fill(ItemStack container, FluidStack resource, boolean doFill) { + return 0; + } + + @Override + public FluidStack drain(ItemStack container, int maxDrain, boolean doDrain) { + return null; + } + + @Override + public IIcon getIconFromDamage(int metadata) { + final Fluid fluid = FluidRegistry.getFluid(metadata); + final IIcon icon = fluid != null ? fluid.getStillIcon() : null; + return icon != null ? icon : FluidRegistry.WATER.getStillIcon(); + } + + @Override + public int getSpriteNumber() { + return 0; + } + + @Override + public int getColorFromItemStack(ItemStack stack, int renderPass) { + final Fluid fluid = stack != null ? FluidRegistry.getFluid(stack.getItemDamage()) : null; + return fluid != null ? fluid.getColor() : 0xFFFFFF; + } + + @Override + public String getItemStackDisplayName(ItemStack stack) { + final Fluid fluid = stack != null ? FluidRegistry.getFluid(stack.getItemDamage()) : null; + return fluid != null ? fluid.getLocalizedName() : super.getItemStackDisplayName(stack); + } + + @Override + public String getUnlocalizedName(ItemStack stack) { + final Fluid fluid = stack != null ? FluidRegistry.getFluid(stack.getItemDamage()) : null; + return fluid != null ? fluid.getUnlocalizedName() : super.getUnlocalizedName(stack); + } + + @Override + @SideOnly(Side.CLIENT) + public void addInformation(ItemStack stack, EntityPlayer player, List tooltip, boolean advanced) { + final Fluid fluid = FluidRegistry.getFluid(stack.getItemDamage()); + + if (fluid == null) { + return; + } + + if (NEIClientConfig.getBooleanSetting("inventory.tooltip.showFluidTemperature")) { + tooltip.add( + EnumChatFormatting.RED + NEIClientUtils.translate( + "inventory.tooltip.temperature.fluid", + NEIClientUtils.formatNumber(fluid.getTemperature()))); + } + + if (NEIClientConfig.getBooleanSetting("inventory.tooltip.showFluidState")) { + tooltip.add( + EnumChatFormatting.GREEN + NEIClientUtils.translate( + "inventory.tooltip.state.fluid", + NEIClientUtils.translate( + fluid.isGaseous() ? "inventory.tooltip.state.fluid.gas" + : "inventory.tooltip.state.fluid.liquid"))); + } + + } + + @Override + public void registerIcons(IIconRegister register) {} + + @Override + @SideOnly(Side.CLIENT) + public void getSubItems(Item aItem, CreativeTabs aTab, List aList) { + for (int i = 0, j = FluidRegistry.getMaxID(); i < j; i++) { + final Fluid fluid = FluidRegistry.getFluid(i); + if (fluid == null) { + continue; + } + + final ItemStack stack = ItemFluidDisplay.createStack(new FluidStack(fluid, 0)); + if (stack != null) { + aList.add(stack); + } + } + } + +} diff --git a/src/main/java/codechicken/nei/recipe/GuiOverlayButton.java b/src/main/java/codechicken/nei/recipe/GuiOverlayButton.java index f9564867..344235da 100644 --- a/src/main/java/codechicken/nei/recipe/GuiOverlayButton.java +++ b/src/main/java/codechicken/nei/recipe/GuiOverlayButton.java @@ -29,6 +29,15 @@ import codechicken.nei.util.NEIMouseUtils; public class GuiOverlayButton extends GuiRecipeButton { + protected static DrawableResource notPresent = new DrawableBuilder( + "nei:textures/nei_tabbed_sprites.png", + 0, + 40, + 8, + 8).build(); + protected static DrawableResource present = new DrawableBuilder("nei:textures/nei_tabbed_sprites.png", 8, 40, 8, 8) + .build(); + public enum ItemOverlayFormat { BACKGROUND, @@ -58,11 +67,23 @@ public class GuiOverlayButton extends GuiRecipeButton { } public void draw(ItemOverlayFormat format) { - LayoutManager.drawItemPresenceOverlay( - this.slot.relx, - this.slot.rely, - this.isPresent, - format == ItemOverlayFormat.BACKGROUND); + + if (format == ItemOverlayFormat.BACKGROUND) { + NEIClientUtils.gl2DRenderContext( + () -> drawRect( + this.slot.relx, + this.slot.rely, + this.slot.width, + this.slot.height, + isPresent ? 0x8000AA00 : 0x80AA0000)); + } else { + final DrawableResource icon = isPresent ? present : notPresent; + LayoutManager.drawIcon( + this.slot.relx + this.slot.width - icon.width, + this.slot.rely + this.slot.height - icon.height, + icon); + } + } } @@ -256,6 +277,11 @@ public class GuiOverlayButton extends GuiRecipeButton { return this.itemPresenceCache; } + @Override + public void onPermutationsChanged() { + this.itemPresenceCache.clear(); + } + public void setRequireShiftForOverlayRecipe(boolean require) { this.requireShiftForOverlayRecipe = require; updateEnabled(); @@ -291,30 +317,15 @@ public class GuiOverlayButton extends GuiRecipeButton { } protected List presenceOverlay(List ingredients) { - final List states = new ArrayList<>(); - final List invStacks = this.firstGui.inventorySlots.inventorySlots.stream() - .filter( - s -> s != null && s.getStack() != null - && s.getStack().stackSize > 0 - && s.isItemValid(s.getStack()) - && s.canTakeStack(this.firstGui.mc.thePlayer)) - .map(s -> s.getStack().copy()).collect(Collectors.toCollection(ArrayList::new)); - - for (PositionedStack stack : ingredients) { - boolean found = false; - - for (ItemStack is : invStacks) { - if (is.stackSize > 0 && stack.contains(is)) { - is.stackSize--; - found = true; - break; - } - } - - states.add(new ItemOverlayState(stack, found)); - } - - return states; + return NEIClientUtils.presenceOverlay( + ingredients, + this.firstGui.inventorySlots.inventorySlots.stream() + .filter( + s -> s != null && s.getStack() != null + && s.getStack().stackSize > 0 + && s.isItemValid(s.getStack()) + && s.canTakeStack(this.firstGui.mc.thePlayer)) + .map(s -> s.getStack().copy()).collect(Collectors.toList())); } public void overlayRecipe(boolean shift) { diff --git a/src/main/java/codechicken/nei/recipe/GuiRecipeButton.java b/src/main/java/codechicken/nei/recipe/GuiRecipeButton.java index 0dbc478a..f24d9f92 100644 --- a/src/main/java/codechicken/nei/recipe/GuiRecipeButton.java +++ b/src/main/java/codechicken/nei/recipe/GuiRecipeButton.java @@ -65,6 +65,10 @@ public abstract class GuiRecipeButton extends GuiNEIButton { } + public void onPermutationsChanged() { + + } + public boolean mouseScrolled(int scroll) { return false; } diff --git a/src/main/java/codechicken/nei/recipe/NEIRecipeWidget.java b/src/main/java/codechicken/nei/recipe/NEIRecipeWidget.java index a761b49a..2856e66a 100644 --- a/src/main/java/codechicken/nei/recipe/NEIRecipeWidget.java +++ b/src/main/java/codechicken/nei/recipe/NEIRecipeWidget.java @@ -175,6 +175,10 @@ public class NEIRecipeWidget extends Widget { if (!NEIClientUtils.shiftKey() && ((this.cycleticks++) / 20) != this.lastcycle || this.lastcycle == -1) { this.lastcycle = this.cycleticks / 20; updatePermutations(); + + for (GuiRecipeButton button : getRecipeButtonsIfInit()) { + button.onPermutationsChanged(); + } } for (GuiRecipeButton button : getRecipeButtons()) { diff --git a/src/main/java/codechicken/nei/recipe/StackInfo.java b/src/main/java/codechicken/nei/recipe/StackInfo.java index ca4ad512..983c73eb 100644 --- a/src/main/java/codechicken/nei/recipe/StackInfo.java +++ b/src/main/java/codechicken/nei/recipe/StackInfo.java @@ -21,6 +21,7 @@ import codechicken.nei.LRUCache; import codechicken.nei.api.IStackStringifyHandler; import codechicken.nei.api.ItemInfo; import codechicken.nei.recipe.stackinfo.DefaultStackStringifyHandler; +import codechicken.nei.recipe.stackinfo.FluidDisplayStackStringifyHandler; import codechicken.nei.recipe.stackinfo.GTFluidStackStringifyHandler; import codechicken.nei.util.ItemStackKey; import codechicken.nei.util.NBTHelper; @@ -36,6 +37,7 @@ public class StackInfo { static { stackStringifyHandlers.add(new DefaultStackStringifyHandler()); + stackStringifyHandlers.add(new FluidDisplayStackStringifyHandler()); stackStringifyHandlers.add(new GTFluidStackStringifyHandler()); } @@ -86,6 +88,19 @@ public class StackInfo { return result == null ? stack : result; } + public static boolean isFluidDisplayItem(ItemStack stack) { + if (stack == null) { + return false; + } + + for (int i = stackStringifyHandlers.size() - 1; i >= 0; i--) { + if (stackStringifyHandlers.get(i).isFluidDisplayItem(stack)) { + return true; + } + } + return false; + } + public static void pauseItemDamageSound(boolean pause) { if (isPausedItemDamageSound != (isPausedItemDamageSound = pause)) { for (IStackStringifyHandler handler : stackStringifyHandlers) { diff --git a/src/main/java/codechicken/nei/recipe/debug/LabelWidget.java b/src/main/java/codechicken/nei/recipe/debug/LabelWidget.java index 3918de13..4031a082 100644 --- a/src/main/java/codechicken/nei/recipe/debug/LabelWidget.java +++ b/src/main/java/codechicken/nei/recipe/debug/LabelWidget.java @@ -40,7 +40,7 @@ public class LabelWidget extends Widget implements IUpdatableWidget { @Override public List handleTooltip(int mx, int my, List tooltip) { - if (contains(mx, my)) { + if (contains(mx, my) && this.value != null) { tooltip.add(this.value); } diff --git a/src/main/java/codechicken/nei/recipe/stackinfo/DefaultStackStringifyHandler.java b/src/main/java/codechicken/nei/recipe/stackinfo/DefaultStackStringifyHandler.java index 953e5c6e..250a6ced 100644 --- a/src/main/java/codechicken/nei/recipe/stackinfo/DefaultStackStringifyHandler.java +++ b/src/main/java/codechicken/nei/recipe/stackinfo/DefaultStackStringifyHandler.java @@ -1,9 +1,14 @@ package codechicken.nei.recipe.stackinfo; +import net.minecraft.block.Block; +import net.minecraft.block.BlockLiquid; +import net.minecraft.block.material.Material; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidContainerRegistry; +import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.IFluidContainerItem; @@ -49,8 +54,24 @@ public class DefaultStackStringifyHandler implements IStackStringifyHandler { public FluidStack getFluid(ItemStack stack) { FluidStack fluidStack = FluidContainerRegistry.getFluidForFilledItem(stack); - if (fluidStack == null && stack.getItem() instanceof IFluidContainerItem) { - fluidStack = ((IFluidContainerItem) stack.getItem()).getFluid(stack); + if (fluidStack == null && stack.getItem() instanceof IFluidContainerItem container) { + fluidStack = container.getFluid(stack); + } + + if (fluidStack == null && Block.getBlockFromItem(stack.getItem()) instanceof BlockLiquid liquidBlock) { + Fluid fluid = FluidRegistry.lookupFluidForBlock(liquidBlock); + + if (fluid == null) { + if (liquidBlock.getMaterial() == Material.water) { + fluid = FluidRegistry.WATER; + } else if (liquidBlock.getMaterial() == Material.lava) { + fluid = FluidRegistry.LAVA; + } + } + + if (fluid != null) { + fluidStack = new FluidStack(fluid, FluidContainerRegistry.BUCKET_VOLUME); + } } return fluidStack; diff --git a/src/main/java/codechicken/nei/recipe/stackinfo/FluidDisplayStackStringifyHandler.java b/src/main/java/codechicken/nei/recipe/stackinfo/FluidDisplayStackStringifyHandler.java new file mode 100644 index 00000000..cc2ec0a8 --- /dev/null +++ b/src/main/java/codechicken/nei/recipe/stackinfo/FluidDisplayStackStringifyHandler.java @@ -0,0 +1,77 @@ +package codechicken.nei.recipe.stackinfo; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; + +import codechicken.nei.api.IStackStringifyHandler; +import codechicken.nei.item.ItemFluidDisplay; + +public class FluidDisplayStackStringifyHandler implements IStackStringifyHandler { + + public static final String NBT_FLUID_NAME = "neiFluidName"; + + @Override + public boolean isFluidDisplayItem(ItemStack stack) { + return stack.getItem() instanceof ItemFluidDisplay; + } + + @Override + public NBTTagCompound convertItemStackToNBT(ItemStack stack, boolean saveStackSize) { + + if (!(stack.getItem() instanceof ItemFluidDisplay)) { + return null; + } + + final FluidStack fluidStack = ((ItemFluidDisplay) stack.getItem()).getFluid(stack); + + if (fluidStack == null) { + return null; + } + + final NBTTagCompound nbTag = new NBTTagCompound(); + nbTag.setString(NBT_FLUID_NAME, fluidStack.getFluid().getName()); + nbTag.setInteger("Count", saveStackSize ? fluidStack.amount : 1); + + if (fluidStack.tag != null) { + nbTag.setTag("FluidTag", fluidStack.tag.copy()); + } + + return nbTag; + } + + @Override + public ItemStack convertNBTToItemStack(NBTTagCompound nbtTag) { + + if (!nbtTag.hasKey(NBT_FLUID_NAME)) { + return null; + } + + final Fluid fluid = FluidRegistry.getFluid(nbtTag.getString(NBT_FLUID_NAME)); + + if (fluid == null) { + return null; + } + + final FluidStack fluidStack = new FluidStack(fluid, nbtTag.getInteger("Count")); + + if (nbtTag.hasKey("FluidTag")) { + fluidStack.tag = nbtTag.getCompoundTag("FluidTag"); + } + + return ItemFluidDisplay.createStack(fluidStack); + } + + @Override + public FluidStack getFluid(ItemStack stack) { + + if (stack.getItem() instanceof ItemFluidDisplay fluidDisplay) { + return fluidDisplay.getFluid(stack); + } + + return null; + } + +} diff --git a/src/main/java/codechicken/nei/recipe/stackinfo/GTFluidStackStringifyHandler.java b/src/main/java/codechicken/nei/recipe/stackinfo/GTFluidStackStringifyHandler.java index 46b9e220..f0bb93cb 100644 --- a/src/main/java/codechicken/nei/recipe/stackinfo/GTFluidStackStringifyHandler.java +++ b/src/main/java/codechicken/nei/recipe/stackinfo/GTFluidStackStringifyHandler.java @@ -11,13 +11,13 @@ import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; import codechicken.nei.api.IStackStringifyHandler; +import codechicken.nei.item.ItemFluidDisplay; import cpw.mods.fml.common.registry.GameRegistry; import cpw.mods.fml.relauncher.ReflectionHelper; public class GTFluidStackStringifyHandler implements IStackStringifyHandler { protected static Class itemFluidDisplay = null; - protected static Method getFluidDisplayStack = null; protected static Method getFluidFromDisplayStack = null; protected static Class gtMetaGeneratedTool = null; protected static Field playSound = null; @@ -33,7 +33,6 @@ public class GTFluidStackStringifyHandler implements IStackStringifyHandler { "gregtech.common.items.ItemFluidDisplay", "gregtech.common.items.GT_FluidDisplayItem"); getFluidFromDisplayStack = gtUtility.getMethod("getFluidFromDisplayStack", ItemStack.class); - getFluidDisplayStack = gtUtility.getMethod("getFluidDisplayStack", FluidStack.class, boolean.class); gtMetaGeneratedTool = ReflectionHelper.getClass( loader, @@ -45,14 +44,15 @@ public class GTFluidStackStringifyHandler implements IStackStringifyHandler { } } + @Override public NBTTagCompound convertItemStackToNBT(ItemStack stack, boolean saveStackSize) { - if (stack.getItem() != GameRegistry.findItem("ae2fc", "fluid_drop")) { + if (stack != null && isFluidDisplayItem(stack)) { final FluidStack fluidStack = getFluid(stack); if (fluidStack != null) { final NBTTagCompound nbTag = new NBTTagCompound(); - nbTag.setString("gtFluidName", fluidStack.getFluid().getName()); + nbTag.setString(FluidDisplayStackStringifyHandler.NBT_FLUID_NAME, fluidStack.getFluid().getName()); nbTag.setInteger("Count", saveStackSize ? fluidStack.amount : 144); return nbTag; } @@ -61,23 +61,23 @@ public class GTFluidStackStringifyHandler implements IStackStringifyHandler { return null; } + @Override public ItemStack convertNBTToItemStack(NBTTagCompound nbtTag) { - if (getFluidDisplayStack != null && nbtTag.hasKey("gtFluidName")) { + if (nbtTag.hasKey("gtFluidName")) { final String fluidName = nbtTag.getString("gtFluidName"); final Fluid fluid = FluidRegistry.getFluid(fluidName); final int amount = nbtTag.getInteger("Count"); if (fluid != null) { - try { - return (ItemStack) getFluidDisplayStack.invoke(null, new FluidStack(fluid, amount), true); - } catch (Exception e) {} + return ItemFluidDisplay.createStack(new FluidStack(fluid, amount)); } } return null; } + @Override public FluidStack getFluid(ItemStack stack) { final Item item = stack.getItem(); @@ -110,6 +110,7 @@ public class GTFluidStackStringifyHandler implements IStackStringifyHandler { return null; } + @Override public ItemStack normalizeRecipeQueryStack(ItemStack stack) { if (stack.getItem() == GameRegistry.findItem("ae2fc", "fluid_drop") @@ -117,9 +118,7 @@ public class GTFluidStackStringifyHandler implements IStackStringifyHandler { final FluidStack fluidStack = getFluid(stack); if (fluidStack != null) { - try { - return (ItemStack) getFluidDisplayStack.invoke(null, fluidStack, true); - } catch (Exception e) {} + return ItemFluidDisplay.createStack(fluidStack); } } @@ -136,4 +135,11 @@ public class GTFluidStackStringifyHandler implements IStackStringifyHandler { } + @Override + public boolean isFluidDisplayItem(ItemStack stack) { + final Item item = stack.getItem(); + return (itemFluidDisplay != null && itemFluidDisplay.isInstance(item)) + || item == GameRegistry.findItem("ae2fc", "fluid_packet"); + } + } diff --git a/src/main/java/codechicken/nei/search/ModNameFilter.java b/src/main/java/codechicken/nei/search/ModNameFilter.java index 29a12540..cc5c9afd 100644 --- a/src/main/java/codechicken/nei/search/ModNameFilter.java +++ b/src/main/java/codechicken/nei/search/ModNameFilter.java @@ -1,13 +1,17 @@ package codechicken.nei.search; +import java.util.HashMap; +import java.util.Map; import java.util.regex.Pattern; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidRegistry; import codechicken.nei.NEIClientConfig; import codechicken.nei.api.ItemFilter; import codechicken.nei.api.ItemInfo; +import codechicken.nei.item.ItemFluidDisplay; import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.ModContainer; import cpw.mods.fml.common.registry.GameRegistry; @@ -15,6 +19,7 @@ import cpw.mods.fml.common.registry.GameRegistry.UniqueIdentifier; public class ModNameFilter implements ItemFilter { + private static final Map fluidOwners = new HashMap<>(); private final Pattern pattern; public ModNameFilter(Pattern pattern) { @@ -23,31 +28,52 @@ public class ModNameFilter implements ItemFilter { @Override public boolean matches(ItemStack itemStack) { - return this.pattern.matcher(nameFromStack(itemStack.getItem())).find(); + return this.pattern.matcher(nameFromStack(itemStack)).find(); } - protected static String nameFromStack(Item item) { + protected static String nameFromStack(ItemStack itemStack) { try { - ModContainer mod = Loader.instance().getIndexedModList().get(getModId(item)); + ModContainer mod = Loader.instance().getIndexedModList().get(getModId(itemStack)); return mod == null ? "Minecraft" : mod.getName(); - } catch (NullPointerException e) { + } catch (Throwable e) { return ""; } } - protected static String getModId(Item item) { + protected static String getModId(ItemStack itemStack) { - if (!ItemInfo.itemOwners.containsKey(item)) { + if (itemStack.getItem() instanceof ItemFluidDisplay fluidDisplay) { + return getFluidModId(fluidDisplay, itemStack); + } + + if (!ItemInfo.itemOwners.containsKey(itemStack.getItem())) { try { - UniqueIdentifier ident = GameRegistry.findUniqueIdentifierFor(item); - ItemInfo.itemOwners.put(item, ident.modId); + final UniqueIdentifier identifier = GameRegistry.findUniqueIdentifierFor(itemStack.getItem()); + ItemInfo.itemOwners.put(itemStack.getItem(), identifier.modId); } catch (Exception ignored) { - NEIClientConfig.logger.error("Failed to find identifier for: " + item); - ItemInfo.itemOwners.put(item, "Unknown"); + NEIClientConfig.logger.error("Failed to find identifier for: " + itemStack.getItem()); + ItemInfo.itemOwners.put(itemStack.getItem(), "Unknown"); } } - return ItemInfo.itemOwners.get(item); + return ItemInfo.itemOwners.get(itemStack.getItem()); + } + + private static String getFluidModId(ItemFluidDisplay fluidDisplay, ItemStack itemStack) { + final Fluid fluid = FluidRegistry.getFluid(itemStack.getItemDamage()); + final String fluidName = FluidRegistry.getDefaultFluidName(fluid); + + if (!fluidOwners.containsKey(fluidName)) { + try { + final UniqueIdentifier identifier = new UniqueIdentifier(fluidName); + fluidOwners.put(fluidName, identifier.modId); + } catch (Exception ignored) { + NEIClientConfig.logger.error("Failed to find identifier for fluid: " + fluidName); + fluidOwners.put(fluidName, "Unknown"); + } + } + + return fluidOwners.get(fluidName); } } diff --git a/src/main/resources/assets/nei/cfg/collapsibleitems.cfg b/src/main/resources/assets/nei/cfg/collapsibleitems.cfg index f3c43cc1..3867b19b 100644 --- a/src/main/resources/assets/nei/cfg/collapsibleitems.cfg +++ b/src/main/resources/assets/nei/cfg/collapsibleitems.cfg @@ -25,4 +25,6 @@ minecraft:record_ #splash potion minecraft:potion 16000-17000 #lingering potion -minecraft:potion 8000-9000 \ No newline at end of file +minecraft:potion 8000-9000 +#fluid display +neifluiddisplay \ No newline at end of file diff --git a/src/main/resources/assets/nei/csv/handlers.csv b/src/main/resources/assets/nei/csv/handlers.csv index 4a17d169..3595981e 100644 --- a/src/main/resources/assets/nei/csv/handlers.csv +++ b/src/main/resources/assets/nei/csv/handlers.csv @@ -44,14 +44,14 @@ com.rwtema.extrautils.nei.InfoHandler,Extra Utilities,ExtraUtilities:chandelier, com.rwtema.extrautils.nei.MicroBlocksHandler,Extra Utilities,ExtraUtilities:microblocks:1,,ExtraUtilities,TRUE,,,,,,,,,,,, com.rwtema.extrautils.nei.SoulHandler,Extra Utilities,ExtraUtilities:mini-soul,,ExtraUtilities,TRUE,,,,,,,,,,,, hellfirepvp.beebetteratbees.client.gui.BBABGuiRecipeTreeHandler,Bees,Forestry:beeQueenGE,,Forestry,TRUE,,,140,,2,,,,,,, -forestry.factory.recipes.nei.NEIHandlerBottler,Forestry for Minecraft,Forestry:factory,,Forestry,TRUE,,,84,,5,,,,,,, -forestry.factory.recipes.nei.NEIHandlerCarpenter,Forestry for Minecraft,Forestry:factory:1,,Forestry,TRUE,,,81,,5,,,,,,, +forestry.factory.recipes.nei.NEIHandlerBottler,Forestry for Minecraft,Forestry:factory,,Forestry,TRUE,,,71,,5,,,,,,, +forestry.factory.recipes.nei.NEIHandlerCarpenter,Forestry for Minecraft,Forestry:factory:1,,Forestry,TRUE,,,95,,5,,,,,,, forestry.factory.recipes.nei.NEIHandlerCentrifuge,Forestry for Minecraft,Forestry:factory:2,,Forestry,TRUE,,,81,,5,,,,,,, forestry.factory.recipes.nei.NEIHandlerFabricator,Forestry for Minecraft,Forestry:factory2,,Forestry,TRUE,,,,,,,,,,,, -forestry.factory.recipes.nei.NEIHandlerFermenter,Forestry for Minecraft,Forestry:factory:3,,Forestry,TRUE,,,81,,5,,,,,,, -forestry.factory.recipes.nei.NEIHandlerMoistener,Forestry for Minecraft,Forestry:factory:4,,Forestry,TRUE,,,84,,5,,,,,,, -forestry.factory.recipes.nei.NEIHandlerSqueezer,Forestry for Minecraft,Forestry:factory:5,,Forestry,TRUE,,,84,,5,,,,,,, -forestry.factory.recipes.nei.NEIHandlerStill,Forestry for Minecraft,Forestry:factory:6,,Forestry,TRUE,,,81,,5,,,,,,, +forestry.factory.recipes.nei.NEIHandlerFermenter,Forestry for Minecraft,Forestry:factory:3,,Forestry,TRUE,,2,69,,5,,,,,,, +forestry.factory.recipes.nei.NEIHandlerMoistener,Forestry for Minecraft,Forestry:factory:4,,Forestry,TRUE,,1,70,,5,,,,,,, +forestry.factory.recipes.nei.NEIHandlerSqueezer,Forestry for Minecraft,Forestry:factory:5,,Forestry,TRUE,,,98,,5,,,,,,, +forestry.factory.recipes.nei.NEIHandlerStill,Forestry for Minecraft,Forestry:factory:6,,Forestry,TRUE,,2,69,,5,,,,,,, net.bdew.neiaddons.forestry.bees.BeeBreedingHandler,Forestry for Minecraft,Forestry:beeQueenGE,,Forestry,TRUE,,,65,,5,,,,,,, net.bdew.neiaddons.forestry.bees.BeeProduceHandler,Forestry for Minecraft,Forestry:beeQueenGE,,Forestry,TRUE,,,65,,5,,,,,,, net.bdew.neiaddons.forestry.butterflies.ButterflyBreedingHandler,Forestry for Minecraft,Forestry:butterflyGE,,Forestry,TRUE,,,,,,,,,,,, diff --git a/src/main/resources/assets/nei/lang/en_US.lang b/src/main/resources/assets/nei/lang/en_US.lang index 3fd9c011..c3695353 100644 --- a/src/main/resources/assets/nei/lang/en_US.lang +++ b/src/main/resources/assets/nei/lang/en_US.lang @@ -123,7 +123,14 @@ nei.inventory.current.gamemode.2=Current gamemode: creative+ nei.inventory.current.gamemode.3=Current gamemode: adventure nei.inventory.tooltip.page=Page: %s / %s [Press %s to see next page] nei.inventory.tooltip.count.item=Count: %s + +itemGroup.neiFluids=Fluids + nei.inventory.tooltip.count.fluid=Amount: %s +nei.inventory.tooltip.temperature.fluid=Temperature: %sK +nei.inventory.tooltip.state.fluid=State: %s +nei.inventory.tooltip.state.fluid.gas=Gas +nei.inventory.tooltip.state.fluid.liquid=Liquid nei.inventory.gamemode.0=Click: Set gamemode to survival nei.inventory.gamemode.1=Click: Set gamemode to creative @@ -486,6 +493,14 @@ nei.options.inventory.itemUntranslator=Item Untranslator nei.options.inventory.itemUntranslator.true=Enabled nei.options.inventory.itemUntranslator.false=Disabled +nei.options.inventory.tooltip=Tooltips +nei.options.inventory.tooltip.showFluidTemperature=Show Fluid Temperature +nei.options.inventory.tooltip.showFluidTemperature.true=Yes +nei.options.inventory.tooltip.showFluidTemperature.false=No +nei.options.inventory.tooltip.showFluidState=Show Fluid State +nei.options.inventory.tooltip.showFluidState.true=Yes +nei.options.inventory.tooltip.showFluidState.false=No + nei.options.command=Commands nei.options.command.creative=Gamemode nei.options.command.creative.tip={0} = 1 for creative, 0 for survival, {1} = player @@ -576,6 +591,7 @@ nei.debug.RecipeHandler.reset=Reset nei.recipe.page=Page %s/%s nei.recipe.tooltip=Recipes +nei.recipe.fluid.tank.amount=Amount: %s nei.recipe.tab.view_all.tooltip=View all categories nei.recipe.search.tooltip.name=Filter Syntax nei.recipe.search.tooltip.shift=§7Hold §6Shift§7 for more info @@ -674,6 +690,7 @@ nei.subsets.Items.Armor.Boots=Boots nei.subsets.Items.Armor.Chestplates=Chestplates nei.subsets.Items.Armor.Helmets=Helmets nei.subsets.Items.Armor.Leggings=Leggings +nei.subsets.Items.Fluids=Fluids nei.subsets.Items.Food=Food nei.subsets.Items.Potions=Potions nei.subsets.Items.Potions.Ingredients=Ingredients diff --git a/src/main/resources/assets/nei/lang/ru_RU.lang b/src/main/resources/assets/nei/lang/ru_RU.lang index f852421c..6a1da14f 100644 --- a/src/main/resources/assets/nei/lang/ru_RU.lang +++ b/src/main/resources/assets/nei/lang/ru_RU.lang @@ -84,6 +84,13 @@ nei.inventory.current.gamemode.2=Текущий режим игры: творч nei.inventory.current.gamemode.3=Текущий режим игры: приключение nei.inventory.tooltip.page=Страница: %s / %s [Нажмите %s для перехода на следующую страницу] +itemGroup.neiFluids=Жидкости + +nei.inventory.tooltip.temperature.fluid=Температура: %sK +nei.inventory.tooltip.state.fluid=Состояние: %s +nei.inventory.tooltip.state.fluid.gas=Газ +nei.inventory.tooltip.state.fluid.liquid=Жидкость + nei.inventory.gamemode.0=Клик: Установить режим игры на выживание nei.inventory.gamemode.1=Клик: Установить режим игры на творческий nei.inventory.gamemode.2=Клик: Установить режим игры на творческий+ @@ -444,6 +451,7 @@ nei.subsets.Items.Armor.Boots=Ботинки nei.subsets.Items.Armor.Chestplates=Нагрудники nei.subsets.Items.Armor.Helmets=Шлемы nei.subsets.Items.Armor.Leggings=Поножи +nei.subsets.Items.Fluids=Жидкости nei.subsets.Items.Food=Еда nei.subsets.Items.Potions=Зелья nei.subsets.Items.Potions.Ingredients=Ингредиенты