Add Flowinf Texture to PositionStack (#1047)

This commit is contained in:
slprime authored and GitHub committed 2026-09-26 01:06:38 +03:00
1 parent 382278bebb
commit 3c472a02cb
3 files changed
+154 -68

No files matched your search

@@ -6,22 +6,18 @@ 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;
import codechicken.nei.item.FluidDrawer;
import codechicken.nei.item.FluidDrawer.FillDirection;
import codechicken.nei.recipe.Badge;
import codechicken.nei.recipe.GuiRecipe;
import codechicken.nei.recipe.StackInfo;
@@ -255,7 +251,9 @@ public class PositionedStack implements Cloneable {
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;
protected int capacity = 0;
protected boolean flowingTexture = false;
protected FillDirection fillDirection = FillDirection.AUTO;
private ItemStack cachedFluidItem;
private FluidStack cachedFluidStack;
@@ -272,7 +270,34 @@ public class PositionedStack implements Cloneable {
super(object, x, y, false);
this.width = width;
this.height = height;
this.capacity = capacity;
setCapacity(capacity);
}
public int getCapacity() {
return this.capacity;
}
public Fluid setCapacity(int capacity) {
this.capacity = Math.max(capacity, 0);
return this;
}
public boolean hasFlowingTexture() {
return this.flowingTexture;
}
public Fluid setFlowingTexture(boolean flowingTexture) {
this.flowingTexture = flowingTexture;
return this;
}
public FillDirection getFillDirection() {
return this.fillDirection;
}
public Fluid setFillDirection(FillDirection fillDirection) {
this.fillDirection = fillDirection == null ? FillDirection.AUTO : fillDirection;
return this;
}
protected FluidStack getFluidStack() {
@@ -313,62 +338,15 @@ public class PositionedStack implements Cloneable {
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);
FluidDrawer.drawFluid(
this.relx,
this.rely,
this.width,
this.height,
this.capacity,
fluidStack,
this.flowingTexture,
this.fillDirection);
}
}
}
@@ -0,0 +1,108 @@
package codechicken.nei.item;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.util.IIcon;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class FluidDrawer {
public enum FillDirection {
AUTO,
UP,
DOWN,
LEFT,
RIGHT;
public boolean isHorizontal() {
return this == LEFT || this == RIGHT;
}
public FillDirection resolve(FluidStack fluidStack) {
if (this != AUTO) return this;
return fluidStack.getFluid().isGaseous(fluidStack) ? DOWN : UP;
}
}
private FluidDrawer() {}
public static void drawFluid(int x, int y, int width, int height, int capacity, FluidStack fluidStack,
boolean flowing, FillDirection direction) {
final Fluid fluid = fluidStack.getFluid();
IIcon icon = flowing ? fluid.getFlowingIcon() : null;
if (icon == null) {
icon = fluid.getIcon(fluidStack);
}
if (icon == null || fluidStack.amount <= 0) {
return;
}
direction = direction.resolve(fluidStack);
final int tankSize = direction.isHorizontal() ? width : height;
final int tankCapacity = capacity > 0 ? capacity : fluidStack.amount;
final int fillSize = Math
.max(1, (int) ((long) tankSize * Math.min(fluidStack.amount, tankCapacity) / tankCapacity));
final int fillWidth = direction.isHorizontal() ? Math.min(fillSize, width) : width;
final int fillHeight = direction.isHorizontal() ? height : Math.min(fillSize, height);
final int fillX = direction == FillDirection.LEFT ? x + width - fillWidth : x;
final int fillY = direction == FillDirection.DOWN ? y : y + height - fillHeight;
final boolean anchorRight = direction == FillDirection.LEFT;
final boolean anchorBottom = direction != FillDirection.DOWN;
final int color = fluid.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.glColor3f(red, green, blue);
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 < fillWidth; tx += 16) {
final int tileWidth = Math.min(16, fillWidth - tx);
// a cropped tile keeps the texture edge that stays seamless against the neighbouring tile
final double uSize = (icon.getMaxU() - icon.getMinU()) * tileWidth / 16D;
final double uMin = anchorRight ? icon.getMaxU() - uSize : icon.getMinU();
final double uMax = anchorRight ? icon.getMaxU() : icon.getMinU() + uSize;
final int leftX = anchorRight ? fillX + fillWidth - tx - tileWidth : fillX + tx;
final int rightX = leftX + tileWidth;
for (int ty = 0; ty < fillHeight; ty += 16) {
final int tileHeight = Math.min(16, fillHeight - ty);
final double vSize = (icon.getMaxV() - icon.getMinV()) * tileHeight / 16D;
final double vMin = anchorBottom ? icon.getMaxV() - vSize : icon.getMinV();
final double vMax = anchorBottom ? icon.getMaxV() : icon.getMinV() + vSize;
final int bottomY = anchorBottom ? fillY + fillHeight - ty : fillY + ty + tileHeight;
final int topY = bottomY - tileHeight;
tessellator.addVertexWithUV(leftX, bottomY, 0, uMin, vMax);
tessellator.addVertexWithUV(rightX, bottomY, 0, uMax, vMax);
tessellator.addVertexWithUV(rightX, topY, 0, uMax, vMin);
tessellator.addVertexWithUV(leftX, topY, 0, uMin, vMin);
}
}
tessellator.draw();
GL11.glDisable(GL11.GL_BLEND);
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glColor4f(1F, 1F, 1F, 1F);
}
}
@@ -228,11 +228,11 @@ com.djgiannuzz.thaumcraftneiplugin.nei.recipehandler.InfusionRecipeHandler,Thaum
ru.timeconqueror.tcneiadditions.nei.arcaneworkbench.ArcaneCraftingShapedHandler,Thaumcraft,Thaumcraft:blockTable:15,,Thaumcraft,TRUE,,4,138,,2,,,,,,,
ru.timeconqueror.tcneiadditions.nei.AspectCombinationHandler,Thaumcraft,Thaumcraft:ItemResearchNotes,,Thaumcraft,TRUE,,,130,,2,,,,,,In sets of 5. Each one is ~30 height,
ru.timeconqueror.tcneiadditions.nei.AspectFromItemStackHandler,Thaumcraft,Thaumcraft:ItemResearchNotes,,Thaumcraft,TRUE,,,140,,2,,,,,,,
tconstruct.plugins.nei.RecipeHandlerAlloying,Tinker's Construct,TConstruct:Smeltery,,TConstruct,TRUE,,,65,,5,,,,,,,
tconstruct.plugins.nei.RecipeHandlerCastingBasin,Tinker's Construct,TConstruct:SearedBlock:2,,TConstruct,TRUE,,,65,,5,,,,,,,
tconstruct.plugins.nei.RecipeHandlerCastingTable,Tinker's Construct,TConstruct:SearedBlock,,TConstruct,TRUE,,,65,,5,,,,,,,
tconstruct.plugins.nei.RecipeHandlerAlloying,Tinker's Construct,TConstruct:Smeltery,,TConstruct,TRUE,,3,63,,5,,,,,,,
tconstruct.plugins.nei.RecipeHandlerCastingBasin,Tinker's Construct,TConstruct:SearedBlock:2,,TConstruct,TRUE,,2,57,,5,,,,,,,
tconstruct.plugins.nei.RecipeHandlerCastingTable,Tinker's Construct,TConstruct:SearedBlock,,TConstruct,TRUE,,2,57,,5,,,,,,,
tconstruct.plugins.nei.RecipeHandlerDryingRack,Tinker's Construct,TConstruct:Armor.DryingRack,,TConstruct,TRUE,,,55,,5,,,,,,,
tconstruct.plugins.nei.RecipeHandlerMelting,Tinker's Construct,TConstruct:LavaTank:2,,TConstruct,TRUE,,,65,,5,,,,,,,
tconstruct.plugins.nei.RecipeHandlerMelting,Tinker's Construct,TConstruct:LavaTank:2,,TConstruct,TRUE,,-1,60,,5,,,,,,,
tconstruct.plugins.nei.RecipeHandlerToolMaterials,Tinker's Construct,TConstruct:ToolStationBlock,,TConstruct,TRUE,,,110,,3,,,,,,"Longer if more modifiers, I went through the whole list",
net.p455w0rd.wirelesscraftingterminal.integration.modules.NEIHelpers.NEIAEShapedRecipeHandler,Wireless Crafting Terminal,ae2wct:wirelessCraftingTerminal,,ae2wct,TRUE,,,,,,,,,,,,
alkalus.main.nei.NEI_Handler_Cauldron,Witchery,witchery:cauldron,,WitcheryExtras,TRUE,,,65,,5,,,,,,,
1 handler modName itemName nbtInfo modId modRequired excludedModId yShift handlerHeight handlerWidth maxRecipesPerPage imageResource imageX imageY imageWidth imageHeight itemNotes useCustomScroll
228 ru.timeconqueror.tcneiadditions.nei.arcaneworkbench.ArcaneCraftingShapedHandler Thaumcraft Thaumcraft:blockTable:15 Thaumcraft TRUE 4 138 2
229 ru.timeconqueror.tcneiadditions.nei.AspectCombinationHandler Thaumcraft Thaumcraft:ItemResearchNotes Thaumcraft TRUE 130 2 In sets of 5. Each one is ~30 height
230 ru.timeconqueror.tcneiadditions.nei.AspectFromItemStackHandler Thaumcraft Thaumcraft:ItemResearchNotes Thaumcraft TRUE 140 2
231 tconstruct.plugins.nei.RecipeHandlerAlloying Tinker's Construct TConstruct:Smeltery TConstruct TRUE 3 65 63 5
232 tconstruct.plugins.nei.RecipeHandlerCastingBasin Tinker's Construct TConstruct:SearedBlock:2 TConstruct TRUE 2 65 57 5
233 tconstruct.plugins.nei.RecipeHandlerCastingTable Tinker's Construct TConstruct:SearedBlock TConstruct TRUE 2 65 57 5
234 tconstruct.plugins.nei.RecipeHandlerDryingRack Tinker's Construct TConstruct:Armor.DryingRack TConstruct TRUE 55 5
235 tconstruct.plugins.nei.RecipeHandlerMelting Tinker's Construct TConstruct:LavaTank:2 TConstruct TRUE -1 65 60 5
236 tconstruct.plugins.nei.RecipeHandlerToolMaterials Tinker's Construct TConstruct:ToolStationBlock TConstruct TRUE 110 3 Longer if more modifiers, I went through the whole list
237 net.p455w0rd.wirelesscraftingterminal.integration.modules.NEIHelpers.NEIAEShapedRecipeHandler Wireless Crafting Terminal ae2wct:wirelessCraftingTerminal ae2wct TRUE
238 alkalus.main.nei.NEI_Handler_Cauldron Witchery witchery:cauldron WitcheryExtras TRUE 65 5