aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/common/render
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/gregtech/common/render')
-rw-r--r--src/main/java/gregtech/common/render/GT_CapeRenderer.java148
-rw-r--r--src/main/java/gregtech/common/render/GT_CopiedBlockTexture.java112
-rw-r--r--src/main/java/gregtech/common/render/GT_CopiedCTMBlockTexture.java118
-rw-r--r--src/main/java/gregtech/common/render/GT_FlaskRenderer.java71
-rw-r--r--src/main/java/gregtech/common/render/GT_FluidDisplayStackRenderer.java98
-rw-r--r--src/main/java/gregtech/common/render/GT_IconFlipped.java91
-rw-r--r--src/main/java/gregtech/common/render/GT_MetaGenerated_Tool_Renderer.java130
-rw-r--r--src/main/java/gregtech/common/render/GT_MultiTexture.java69
-rw-r--r--src/main/java/gregtech/common/render/GT_MultiTile_Renderer.java181
-rw-r--r--src/main/java/gregtech/common/render/GT_PollutionRenderer.java251
-rw-r--r--src/main/java/gregtech/common/render/GT_RenderDrone.java93
-rw-r--r--src/main/java/gregtech/common/render/GT_RenderUtil.java141
-rw-r--r--src/main/java/gregtech/common/render/GT_RenderedTexture.java395
-rw-r--r--src/main/java/gregtech/common/render/GT_Renderer_Block.java747
-rw-r--r--src/main/java/gregtech/common/render/GT_Renderer_Entity_Arrow.java23
-rw-r--r--src/main/java/gregtech/common/render/GT_SidedTexture.java78
-rw-r--r--src/main/java/gregtech/common/render/GT_TextureBase.java31
-rw-r--r--src/main/java/gregtech/common/render/GT_TextureBuilder.java151
-rw-r--r--src/main/java/gregtech/common/render/IRenderedBlock.java114
-rw-r--r--src/main/java/gregtech/common/render/IRenderedBlockSideCheck.java15
-rw-r--r--src/main/java/gregtech/common/render/MultiTileBasicRender.java10
-rw-r--r--src/main/java/gregtech/common/render/items/CosmicNeutroniumRenderer.java109
-rw-r--r--src/main/java/gregtech/common/render/items/GT_DataStick_Renderer.java42
-rw-r--r--src/main/java/gregtech/common/render/items/GT_GeneratedItem_Renderer.java166
-rw-r--r--src/main/java/gregtech/common/render/items/GT_GeneratedMaterial_Renderer.java130
-rw-r--r--src/main/java/gregtech/common/render/items/GT_MetaGenerated_Item_Renderer.java85
-rw-r--r--src/main/java/gregtech/common/render/items/GaiaSpiritRenderer.java27
-rw-r--r--src/main/java/gregtech/common/render/items/InfinityRenderer.java139
-rw-r--r--src/main/java/gregtech/common/render/items/TranscendentMetalRenderer.java145
-rw-r--r--src/main/java/gregtech/common/render/items/UniversiumRenderer.java197
30 files changed, 4107 insertions, 0 deletions
diff --git a/src/main/java/gregtech/common/render/GT_CapeRenderer.java b/src/main/java/gregtech/common/render/GT_CapeRenderer.java
new file mode 100644
index 0000000000..ec9ef2880c
--- /dev/null
+++ b/src/main/java/gregtech/common/render/GT_CapeRenderer.java
@@ -0,0 +1,148 @@
+package gregtech.common.render;
+
+import java.util.Collection;
+
+import net.minecraft.client.entity.AbstractClientPlayer;
+import net.minecraft.client.model.ModelBiped;
+import net.minecraft.client.renderer.entity.RenderManager;
+import net.minecraft.client.renderer.entity.RenderPlayer;
+import net.minecraft.potion.Potion;
+import net.minecraft.util.MathHelper;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.client.event.RenderPlayerEvent;
+
+import org.lwjgl.opengl.GL11;
+
+import gregtech.api.enums.GT_Values;
+import gregtech.api.util.GT_Log;
+import gregtech.api.util.GT_Utility;
+
+public class GT_CapeRenderer extends RenderPlayer {
+
+ private final ResourceLocation[] mCapes = { new ResourceLocation("gregtech:textures/BrainTechCape.png"),
+ new ResourceLocation("gregtech:textures/GregTechCape.png"),
+ new ResourceLocation("gregtech:textures/MrBrainCape.png"),
+ new ResourceLocation("gregtech:textures/GregoriusCape.png"),
+ new ResourceLocation("gregtech:textures/DonorCape.png"), new ResourceLocation("gregtech:textures/DevCape.png"),
+ new ResourceLocation("gregtech:textures/Steam.png"), new ResourceLocation("gregtech:textures/Titanium.png"),
+ new ResourceLocation("gregtech:textures/Neutronium.png"),
+ new ResourceLocation("gregtech:textures/Stargate.png") };
+ private final Collection<String> mCapeList;
+
+ public GT_CapeRenderer(Collection<String> aCapeList) {
+ this.mCapeList = aCapeList;
+ setRenderManager(RenderManager.instance);
+ }
+
+ public void receiveRenderSpecialsEvent(RenderPlayerEvent.Specials.Pre aEvent) {
+ AbstractClientPlayer aPlayer = (AbstractClientPlayer) aEvent.entityPlayer;
+ if (GT_Utility.getFullInvisibility(aPlayer)) {
+ aEvent.setCanceled(true);
+ return;
+ }
+ float aPartialTicks = aEvent.partialRenderTick;
+ if (aPlayer.isInvisible()) {
+ return;
+ }
+ if (GT_Utility.getPotion(aPlayer, Potion.invisibility.id)) {
+ return;
+ }
+ try {
+ ResourceLocation tResource = aPlayer.getLocationCape();
+ if (aPlayer.getDisplayName()
+ .equalsIgnoreCase("Friedi4321")) {
+ tResource = this.mCapes[0];
+ }
+ if (this.mCapeList.contains(
+ aPlayer.getDisplayName()
+ .toLowerCase())) {
+ tResource = this.mCapes[1];
+ }
+ if (aPlayer.getDisplayName()
+ .equalsIgnoreCase("Mr_Brain")) {
+ tResource = this.mCapes[2];
+ }
+ if (aPlayer.getDisplayName()
+ .equalsIgnoreCase("GregoriusT")) {
+ tResource = this.mCapes[3];
+ }
+ if (this.mCapeList.contains(
+ aPlayer.getDisplayName()
+ .toLowerCase() + ":capedonor")) {
+ tResource = this.mCapes[4];
+ }
+ if (this.mCapeList.contains(
+ aPlayer.getDisplayName()
+ .toLowerCase() + ":capedev")) {
+ tResource = this.mCapes[5];
+ }
+ if (this.mCapeList.contains(
+ aPlayer.getDisplayName()
+ .toLowerCase() + ":cape_steam")) {
+ tResource = this.mCapes[6];
+ }
+ if (this.mCapeList.contains(
+ aPlayer.getDisplayName()
+ .toLowerCase() + ":cape_titanium")) {
+ tResource = this.mCapes[7];
+ }
+ if (this.mCapeList.contains(
+ aPlayer.getDisplayName()
+ .toLowerCase() + ":cape_neutronium")) {
+ tResource = this.mCapes[8];
+ }
+ if (this.mCapeList.contains(
+ aPlayer.getDisplayName()
+ .toLowerCase() + ":cape_stargate")) {
+ tResource = this.mCapes[9];
+ }
+
+ if ((tResource != null) && (!aPlayer.getHideCape())) {
+ bindTexture(tResource);
+ GL11.glPushMatrix();
+ GL11.glTranslatef(0.0F, 0.0F, 0.125F);
+ double d0 = aPlayer.field_71091_bM + (aPlayer.field_71094_bP - aPlayer.field_71091_bM) * aPartialTicks
+ - (aPlayer.prevPosX + (aPlayer.posX - aPlayer.prevPosX) * aPartialTicks);
+ double d1 = aPlayer.field_71096_bN + (aPlayer.field_71095_bQ - aPlayer.field_71096_bN) * aPartialTicks
+ - (aPlayer.prevPosY + (aPlayer.posY - aPlayer.prevPosY) * aPartialTicks);
+ double d2 = aPlayer.field_71097_bO + (aPlayer.field_71085_bR - aPlayer.field_71097_bO) * aPartialTicks
+ - (aPlayer.prevPosZ + (aPlayer.posZ - aPlayer.prevPosZ) * aPartialTicks);
+ float f6 = aPlayer.prevRenderYawOffset
+ + (aPlayer.renderYawOffset - aPlayer.prevRenderYawOffset) * aPartialTicks;
+ double d3 = MathHelper.sin(f6 * (float) Math.PI / 180.0F);
+ double d4 = -MathHelper.cos(f6 * (float) Math.PI / 180.0F);
+ float f7 = (float) d1 * 10.0F;
+ float f8 = (float) (d0 * d3 + d2 * d4) * 100.0F;
+ float f9 = (float) (d0 * d4 - d2 * d3) * 100.0F;
+ if (f7 < -6.0F) {
+ f7 = -6.0F;
+ }
+ if (f7 > 32.0F) {
+ f7 = 32.0F;
+ }
+ if (f8 < 0.0F) {
+ f8 = 0.0F;
+ }
+ float f10 = aPlayer.prevCameraYaw + (aPlayer.cameraYaw - aPlayer.prevCameraYaw) * aPartialTicks;
+ f7 += MathHelper.sin(
+ (aPlayer.prevDistanceWalkedModified
+ + (aPlayer.distanceWalkedModified - aPlayer.prevDistanceWalkedModified) * aPartialTicks) * 6.0F)
+ * 32.0F
+ * f10;
+ if (aPlayer.isSneaking()) {
+ f7 += 25.0F;
+ }
+ GL11.glRotatef(6.0F + f8 / 2.0F + f7, 1.0F, 0.0F, 0.0F);
+ GL11.glRotatef(f9 / 2.0F, 0.0F, 0.0F, 1.0F);
+ GL11.glRotatef(-f9 / 2.0F, 0.0F, 1.0F, 0.0F);
+ GL11.glRotatef(180.0F, 0.0F, 1.0F, 0.0F);
+ ((ModelBiped) this.mainModel).renderCloak(0.0625F);
+ GL11.glPopMatrix();
+ }
+ } catch (Throwable e) {
+ if (GT_Values.D1) {
+ e.printStackTrace(GT_Log.err);
+ }
+ }
+ }
+}
diff --git a/src/main/java/gregtech/common/render/GT_CopiedBlockTexture.java b/src/main/java/gregtech/common/render/GT_CopiedBlockTexture.java
new file mode 100644
index 0000000000..937c1a994f
--- /dev/null
+++ b/src/main/java/gregtech/common/render/GT_CopiedBlockTexture.java
@@ -0,0 +1,112 @@
+package gregtech.common.render;
+
+import net.minecraft.block.Block;
+import net.minecraft.client.renderer.RenderBlocks;
+import net.minecraft.util.IIcon;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import gregtech.api.interfaces.IBlockContainer;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.util.LightingHelper;
+
+public class GT_CopiedBlockTexture extends GT_TextureBase implements ITexture, IBlockContainer {
+
+ private final Block mBlock;
+ private final byte mSide, mMeta;
+
+ protected GT_CopiedBlockTexture(Block aBlock, int ordinalSide, int aMeta, short[] aRGBa, boolean allowAlpha) {
+ if (aRGBa.length != 4) throw new IllegalArgumentException("RGBa doesn't have 4 Values @ GT_CopiedBlockTexture");
+ mBlock = aBlock;
+ mSide = (byte) ordinalSide;
+ mMeta = (byte) aMeta;
+ }
+
+ @Override
+ public boolean isOldTexture() {
+ return false;
+ }
+
+ private IIcon getIcon(int ordinalSide) {
+ if (mSide == 6) return mBlock.getIcon(ordinalSide, mMeta);
+ return mBlock.getIcon(mSide, mMeta);
+ }
+
+ @Override
+ public void renderXPos(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ final IIcon aIcon = getIcon(ForgeDirection.EAST.ordinal());
+ aRenderer.field_152631_f = true;
+ startDrawingQuads(aRenderer, 1.0f, 0.0f, 0.0f);
+ new LightingHelper(aRenderer).setupLightingXPos(aBlock, aX, aY, aZ)
+ .setupColor(ForgeDirection.EAST, 0xffffff);
+ aRenderer.renderFaceXPos(aBlock, aX, aY, aZ, aIcon);
+ draw(aRenderer);
+ aRenderer.field_152631_f = false;
+ }
+
+ @Override
+ public void renderXNeg(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ startDrawingQuads(aRenderer, -1.0f, 0.0f, 0.0f);
+ final IIcon aIcon = getIcon(ForgeDirection.WEST.ordinal());
+ new LightingHelper(aRenderer).setupLightingXNeg(aBlock, aX, aY, aZ)
+ .setupColor(ForgeDirection.WEST, 0xffffff);
+ aRenderer.renderFaceXNeg(aBlock, aX, aY, aZ, aIcon);
+ draw(aRenderer);
+ }
+
+ @Override
+ public void renderYPos(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ startDrawingQuads(aRenderer, 0.0f, 1.0f, 0.0f);
+ final IIcon aIcon = getIcon(ForgeDirection.UP.ordinal());
+ new LightingHelper(aRenderer).setupLightingYPos(aBlock, aX, aY, aZ)
+ .setupColor(ForgeDirection.UP, 0xffffff);
+ aRenderer.renderFaceYPos(aBlock, aX, aY, aZ, aIcon);
+ draw(aRenderer);
+ }
+
+ @Override
+ public void renderYNeg(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ startDrawingQuads(aRenderer, 0.0f, -1.0f, 0.0f);
+ final IIcon aIcon = getIcon(ForgeDirection.DOWN.ordinal());
+ new LightingHelper(aRenderer).setupLightingYNeg(aBlock, aX, aY, aZ)
+ .setupColor(ForgeDirection.DOWN, 0xffffff);
+ aRenderer.renderFaceYNeg(aBlock, aX, aY, aZ, aIcon);
+ draw(aRenderer);
+ }
+
+ @Override
+ public void renderZPos(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ startDrawingQuads(aRenderer, 0.0f, 0.0f, 1.0f);
+ final IIcon aIcon = getIcon(ForgeDirection.SOUTH.ordinal());
+ new LightingHelper(aRenderer).setupLightingZPos(aBlock, aX, aY, aZ)
+ .setupColor(ForgeDirection.SOUTH, 0xffffff);
+ aRenderer.renderFaceZPos(aBlock, aX, aY, aZ, aIcon);
+ draw(aRenderer);
+ }
+
+ @Override
+ public void renderZNeg(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ startDrawingQuads(aRenderer, 0.0f, 0.0f, -1.0f);
+ final IIcon aIcon = getIcon(ForgeDirection.NORTH.ordinal());
+ aRenderer.field_152631_f = true;
+ new LightingHelper(aRenderer).setupLightingZNeg(aBlock, aX, aY, aZ)
+ .setupColor(ForgeDirection.NORTH, 0xffffff);
+ aRenderer.renderFaceZNeg(aBlock, aX, aY, aZ, aIcon);
+ draw(aRenderer);
+ aRenderer.field_152631_f = false;
+ }
+
+ @Override
+ public boolean isValidTexture() {
+ return mBlock != null;
+ }
+
+ @Override
+ public Block getBlock() {
+ return mBlock;
+ }
+
+ @Override
+ public byte getMeta() {
+ return mMeta;
+ }
+}
diff --git a/src/main/java/gregtech/common/render/GT_CopiedCTMBlockTexture.java b/src/main/java/gregtech/common/render/GT_CopiedCTMBlockTexture.java
new file mode 100644
index 0000000000..17fa9ac8ff
--- /dev/null
+++ b/src/main/java/gregtech/common/render/GT_CopiedCTMBlockTexture.java
@@ -0,0 +1,118 @@
+package gregtech.common.render;
+
+import net.minecraft.block.Block;
+import net.minecraft.client.renderer.RenderBlocks;
+import net.minecraft.util.IIcon;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import gregtech.api.interfaces.IBlockContainer;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.util.GT_RenderingWorld;
+import gregtech.api.util.LightingHelper;
+
+class GT_CopiedCTMBlockTexture extends GT_TextureBase implements ITexture, IBlockContainer {
+
+ private final Block mBlock;
+ private final byte mSide, mMeta;
+
+ GT_CopiedCTMBlockTexture(Block aBlock, int ordinalSide, int aMeta, short[] aRGBa, boolean allowAlpha) {
+ if (aRGBa.length != 4)
+ throw new IllegalArgumentException("RGBa doesn't have 4 Values @ GT_CopiedCTMBlockTexture");
+ mBlock = aBlock;
+ mSide = (byte) ordinalSide;
+ mMeta = (byte) aMeta;
+ }
+
+ @Override
+ public boolean isOldTexture() {
+ return false;
+ }
+
+ private IIcon getIcon(int ordinalSide, int aX, int aY, int aZ, RenderBlocks aRenderer) {
+ final int tSide = mSide == 6 ? ordinalSide : mSide;
+ return mBlock.getIcon(getBlockAccess(aRenderer), aX, aY, aZ, tSide);
+ }
+
+ private GT_RenderingWorld getBlockAccess(RenderBlocks aRenderer) {
+ return GT_RenderingWorld.getInstance(aRenderer.blockAccess);
+ }
+
+ @Override
+ public void renderXPos(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ final IIcon aIcon = getIcon(ForgeDirection.EAST.ordinal(), aX, aY, aZ, aRenderer);
+ aRenderer.field_152631_f = true;
+ startDrawingQuads(aRenderer, 1.0f, 0.0f, 0.0f);
+ new LightingHelper(aRenderer).setupLightingXPos(aBlock, aX, aY, aZ)
+ .setupColor(ForgeDirection.EAST, mBlock.colorMultiplier(getBlockAccess(aRenderer), aX, aY, aZ));
+ aRenderer.renderFaceXPos(aBlock, aX, aY, aZ, aIcon);
+ draw(aRenderer);
+ aRenderer.field_152631_f = false;
+ }
+
+ @Override
+ public void renderXNeg(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ startDrawingQuads(aRenderer, -1.0f, 0.0f, 0.0f);
+ final IIcon aIcon = getIcon(ForgeDirection.WEST.ordinal(), aX, aY, aZ, aRenderer);
+ new LightingHelper(aRenderer).setupLightingXNeg(aBlock, aX, aY, aZ)
+ .setupColor(ForgeDirection.WEST, mBlock.colorMultiplier(getBlockAccess(aRenderer), aX, aY, aZ));
+ aRenderer.renderFaceXNeg(aBlock, aX, aY, aZ, aIcon);
+ draw(aRenderer);
+ }
+
+ @Override
+ public void renderYPos(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ startDrawingQuads(aRenderer, 0.0f, 1.0f, 0.0f);
+ final IIcon aIcon = getIcon(ForgeDirection.UP.ordinal(), aX, aY, aZ, aRenderer);
+ new LightingHelper(aRenderer).setupLightingYPos(aBlock, aX, aY, aZ)
+ .setupColor(ForgeDirection.UP, mBlock.colorMultiplier(getBlockAccess(aRenderer), aX, aY, aZ));
+ aRenderer.renderFaceYPos(aBlock, aX, aY, aZ, aIcon);
+ draw(aRenderer);
+ }
+
+ @Override
+ public void renderYNeg(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ startDrawingQuads(aRenderer, 0.0f, -1.0f, 0.0f);
+ final IIcon aIcon = getIcon(ForgeDirection.DOWN.ordinal(), aX, aY, aZ, aRenderer);
+ new LightingHelper(aRenderer).setupLightingYNeg(aBlock, aX, aY, aZ)
+ .setupColor(ForgeDirection.DOWN, mBlock.colorMultiplier(getBlockAccess(aRenderer), aX, aY, aZ));
+ aRenderer.renderFaceYNeg(aBlock, aX, aY, aZ, aIcon);
+ draw(aRenderer);
+ }
+
+ @Override
+ public void renderZPos(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ startDrawingQuads(aRenderer, 0.0f, 0.0f, 1.0f);
+ final IIcon aIcon = getIcon(ForgeDirection.SOUTH.ordinal(), aX, aY, aZ, aRenderer);
+ new LightingHelper(aRenderer).setupLightingZPos(aBlock, aX, aY, aZ)
+ .setupColor(ForgeDirection.SOUTH, mBlock.colorMultiplier(getBlockAccess(aRenderer), aX, aY, aZ));
+ aRenderer.renderFaceZPos(aBlock, aX, aY, aZ, aIcon);
+ draw(aRenderer);
+ }
+
+ @Override
+ public void renderZNeg(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ startDrawingQuads(aRenderer, 0.0f, 0.0f, -1.0f);
+ final IIcon aIcon = getIcon(ForgeDirection.NORTH.ordinal(), aX, aY, aZ, aRenderer);
+ aRenderer.field_152631_f = true;
+ new LightingHelper(aRenderer).setupLightingZNeg(aBlock, aX, aY, aZ)
+ .setupColor(ForgeDirection.NORTH, mBlock.colorMultiplier(getBlockAccess(aRenderer), aX, aY, aZ));
+ aRenderer.renderFaceZNeg(aBlock, aX, aY, aZ, aIcon);
+ draw(aRenderer);
+ aRenderer.field_152631_f = false;
+ }
+
+ @Override
+ public boolean isValidTexture() {
+ return mBlock != null;
+ }
+
+ @Override
+ public Block getBlock() {
+ return mBlock;
+ }
+
+ @Override
+ public byte getMeta() {
+ return mMeta;
+ }
+}
diff --git a/src/main/java/gregtech/common/render/GT_FlaskRenderer.java b/src/main/java/gregtech/common/render/GT_FlaskRenderer.java
new file mode 100644
index 0000000000..addcb1cf70
--- /dev/null
+++ b/src/main/java/gregtech/common/render/GT_FlaskRenderer.java
@@ -0,0 +1,71 @@
+package gregtech.common.render;
+
+import net.minecraft.client.Minecraft;
+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.client.MinecraftForgeClient;
+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;
+import gregtech.api.enums.ItemList;
+import gregtech.common.items.GT_VolumetricFlask;
+
+@SideOnly(Side.CLIENT)
+public final class GT_FlaskRenderer implements IItemRenderer {
+
+ public GT_FlaskRenderer() {
+ MinecraftForgeClient.registerItemRenderer(ItemList.VOLUMETRIC_FLASK.getItem(), this);
+ }
+
+ @Override
+ public boolean handleRenderType(ItemStack item, ItemRenderType type) {
+ return type != ItemRenderType.FIRST_PERSON_MAP;
+ }
+
+ @Override
+ public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) {
+ return type == ItemRenderType.ENTITY && helper == ItemRendererHelper.ENTITY_BOBBING
+ || (helper == ItemRendererHelper.ENTITY_ROTATION && Minecraft.getMinecraft().gameSettings.fancyGraphics);
+ }
+
+ @Override
+ public void renderItem(ItemRenderType type, ItemStack item, Object... data) {
+ GT_VolumetricFlask cell = (GT_VolumetricFlask) item.getItem();
+ IIcon icon = item.getIconIndex();
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glEnable(GL11.GL_ALPHA_TEST);
+ GT_RenderUtil.applyStandardItemTransform(type);
+
+ FluidStack fs = cell != null ? cell.getFluid(item) : null;
+ if (fs != null) {
+ IIcon iconWindow = cell.iconWindow;
+ Fluid fluid = fs.getFluid();
+ IIcon fluidIcon = fluid.getIcon(fs);
+ int fluidColor = fluid.getColor(fs);
+
+ Minecraft.getMinecraft().renderEngine.bindTexture(TextureMap.locationItemsTexture);
+ GL11.glBlendFunc(GL11.GL_ZERO, GL11.GL_ONE);
+ GT_RenderUtil.renderItem(type, iconWindow);
+
+ Minecraft.getMinecraft().renderEngine.bindTexture(TextureMap.locationBlocksTexture);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GL11.glDepthFunc(GL11.GL_EQUAL);
+ GL11.glColor3ub((byte) (fluidColor >> 16), (byte) (fluidColor >> 8), (byte) fluidColor);
+ GT_RenderUtil.renderItem(type, fluidIcon);
+ GL11.glColor3ub((byte) -1, (byte) -1, (byte) -1);
+ GL11.glDepthFunc(GL11.GL_LEQUAL);
+ }
+
+ Minecraft.getMinecraft().renderEngine.bindTexture(TextureMap.locationItemsTexture);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GT_RenderUtil.renderItem(type, icon);
+ GL11.glDisable(GL11.GL_ALPHA_TEST);
+ GL11.glDisable(GL11.GL_BLEND);
+ }
+}
diff --git a/src/main/java/gregtech/common/render/GT_FluidDisplayStackRenderer.java b/src/main/java/gregtech/common/render/GT_FluidDisplayStackRenderer.java
new file mode 100644
index 0000000000..9a35f6bc57
--- /dev/null
+++ b/src/main/java/gregtech/common/render/GT_FluidDisplayStackRenderer.java
@@ -0,0 +1,98 @@
+package gregtech.common.render;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.renderer.OpenGlHelper;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.IIcon;
+import net.minecraftforge.client.IItemRenderer;
+import net.minecraftforge.client.MinecraftForgeClient;
+
+import org.lwjgl.opengl.GL11;
+
+import appeng.util.ReadableNumberConverter;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import gregtech.api.enums.ItemList;
+import gregtech.api.enums.Materials;
+import gregtech.common.items.GT_FluidDisplayItem;
+
+@SideOnly(Side.CLIENT)
+public class GT_FluidDisplayStackRenderer implements IItemRenderer {
+
+ public GT_FluidDisplayStackRenderer() {
+ MinecraftForgeClient.registerItemRenderer(ItemList.Display_Fluid.getItem(), this);
+ }
+
+ @Override
+ public boolean handleRenderType(ItemStack item, ItemRenderType type) {
+ if (!item.hasTagCompound()) return false;
+ return type == ItemRenderType.INVENTORY;
+ }
+
+ @Override
+ public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) {
+ // not sure what this does.
+ return false;
+ }
+
+ @Override
+ public void renderItem(ItemRenderType type, ItemStack item, Object... data) {
+ if (item == null || item.getItem() == null || !(item.getItem() instanceof GT_FluidDisplayItem)) return;
+
+ OpenGlHelper.glBlendFunc(770, 771, 1, 0);
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glEnable(GL11.GL_ALPHA_TEST);
+
+ Materials associatedFluidMaterial = Materials.get(item.stackTagCompound.getString("mFluidMaterialName"));
+ if (associatedFluidMaterial.renderer == null
+ || !associatedFluidMaterial.renderer.renderFluidDisplayItem(type, item, data)) {
+ IIcon icon = item.getItem()
+ .getIconFromDamage(item.getItemDamage());
+ Tessellator tess = Tessellator.instance;
+ tess.startDrawingQuads();
+ // draw a simple rectangle for the inventory icon
+ final float x_min = icon.getMinU();
+ final float x_max = icon.getMaxU();
+ final float y_min = icon.getMinV();
+ final float y_max = icon.getMaxV();
+ tess.addVertexWithUV(0, 16, 0, x_min, y_max);
+ tess.addVertexWithUV(16, 16, 0, x_max, y_max);
+ tess.addVertexWithUV(16, 0, 0, x_max, y_min);
+ tess.addVertexWithUV(0, 0, 0, x_min, y_min);
+ tess.draw();
+ }
+
+ if (item.getTagCompound() == null) {
+ GL11.glDisable(GL11.GL_BLEND);
+ GL11.glDisable(GL11.GL_ALPHA_TEST);
+ return;
+ }
+
+ // Render Fluid amount text
+ long fluidAmount = item.getTagCompound()
+ .getLong("mFluidDisplayAmount");
+ if (fluidAmount > 0L && !item.getTagCompound()
+ .getBoolean("mHideStackSize")) {
+ String amountString;
+
+ if (fluidAmount < 10_000) {
+ amountString = "" + fluidAmount + "L";
+ } else {
+ amountString = ReadableNumberConverter.INSTANCE.toWideReadableForm(fluidAmount) + "L";
+ }
+
+ FontRenderer fontRender = Minecraft.getMinecraft().fontRenderer;
+ float smallTextScale = fontRender.getUnicodeFlag() ? 3F / 4F : 1F / 2F;
+ 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.glDisable(GL11.GL_ALPHA_TEST);
+ }
+ }
+}
diff --git a/src/main/java/gregtech/common/render/GT_IconFlipped.java b/src/main/java/gregtech/common/render/GT_IconFlipped.java
new file mode 100644
index 0000000000..8258e74ffa
--- /dev/null
+++ b/src/main/java/gregtech/common/render/GT_IconFlipped.java
@@ -0,0 +1,91 @@
+package gregtech.common.render;
+
+import net.minecraft.util.IIcon;
+
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+@SideOnly(Side.CLIENT)
+public class GT_IconFlipped implements IIcon {
+
+ private final IIcon baseIcon;
+ private final boolean flipU;
+ private final boolean flipV;
+
+ public GT_IconFlipped(IIcon baseIcon, boolean flipU, boolean flipV) {
+ this.baseIcon = baseIcon;
+ this.flipU = flipU;
+ this.flipV = flipV;
+ }
+
+ /**
+ * Returns the width of the icon, in pixels.
+ */
+ @Override
+ public int getIconWidth() {
+ return this.baseIcon.getIconWidth();
+ }
+
+ /**
+ * Returns the height of the icon, in pixels.
+ */
+ @Override
+ public int getIconHeight() {
+ return this.baseIcon.getIconHeight();
+ }
+
+ /**
+ * Returns the minimum U coordinate to use when rendering with this icon.
+ */
+ @Override
+ public float getMinU() {
+ return this.flipU ? this.baseIcon.getMaxU() : this.baseIcon.getMinU();
+ }
+
+ /**
+ * Returns the maximum U coordinate to use when rendering with this icon.
+ */
+ @Override
+ public float getMaxU() {
+ return this.flipU ? this.baseIcon.getMinU() : this.baseIcon.getMaxU();
+ }
+
+ /**
+ * Gets a U coordinate on the icon. 0 returns uMin and 16 returns uMax. Other arguments return in-between values.
+ */
+ @Override
+ public float getInterpolatedU(double p_94214_1_) {
+ final float f = this.getMaxU() - this.getMinU();
+ return this.getMinU() + f * ((float) p_94214_1_ / 16.0F);
+ }
+
+ /**
+ * Returns the minimum V coordinate to use when rendering with this icon.
+ */
+ @Override
+ public float getMinV() {
+ return this.flipV ? this.baseIcon.getMaxV() : this.baseIcon.getMinV();
+ }
+
+ /**
+ * Returns the maximum V coordinate to use when rendering with this icon.
+ */
+ @Override
+ public float getMaxV() {
+ return this.flipV ? this.baseIcon.getMinV() : this.baseIcon.getMaxV();
+ }
+
+ /**
+ * Gets a V coordinate on the icon. 0 returns vMin and 16 returns vMax. Other arguments return in-between values.
+ */
+ @Override
+ public float getInterpolatedV(double p_94207_1_) {
+ final float f = this.getMaxV() - this.getMinV();
+ return this.getMinV() + f * ((float) p_94207_1_ / 16.0F);
+ }
+
+ @Override
+ public String getIconName() {
+ return this.baseIcon.getIconName();
+ }
+}
diff --git a/src/main/java/gregtech/common/render/GT_MetaGenerated_Tool_Renderer.java b/src/main/java/gregtech/common/render/GT_MetaGenerated_Tool_Renderer.java
new file mode 100644
index 0000000000..96285a3fc1
--- /dev/null
+++ b/src/main/java/gregtech/common/render/GT_MetaGenerated_Tool_Renderer.java
@@ -0,0 +1,130 @@
+package gregtech.common.render;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.IIcon;
+import net.minecraftforge.client.IItemRenderer;
+import net.minecraftforge.client.MinecraftForgeClient;
+
+import org.lwjgl.opengl.GL11;
+
+import gregtech.GT_Mod;
+import gregtech.api.enums.Materials;
+import gregtech.api.enums.Textures;
+import gregtech.api.interfaces.IIconContainer;
+import gregtech.api.interfaces.IToolStats;
+import gregtech.api.items.GT_MetaGenerated_Tool;
+
+public class GT_MetaGenerated_Tool_Renderer implements IItemRenderer {
+
+ public GT_MetaGenerated_Tool_Renderer() {
+ for (GT_MetaGenerated_Tool tItem : GT_MetaGenerated_Tool.sInstances.values()) {
+ if (tItem != null) {
+ MinecraftForgeClient.registerItemRenderer(tItem, this);
+ }
+ }
+ }
+
+ @Override
+ public boolean handleRenderType(ItemStack stack, ItemRenderType type) {
+ return (type == ItemRenderType.EQUIPPED_FIRST_PERSON) || (type == ItemRenderType.INVENTORY)
+ || (type == ItemRenderType.EQUIPPED)
+ || (type == ItemRenderType.ENTITY);
+ }
+
+ @Override
+ public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack stack, ItemRendererHelper helper) {
+ return type == ItemRenderType.ENTITY && helper == ItemRendererHelper.ENTITY_BOBBING
+ || (helper == ItemRendererHelper.ENTITY_ROTATION && Minecraft.getMinecraft().gameSettings.fancyGraphics);
+ }
+
+ @Override
+ public void renderItem(ItemRenderType type, ItemStack stack, Object... data) {
+ GT_MetaGenerated_Tool item = (GT_MetaGenerated_Tool) stack.getItem();
+ GL11.glEnable(GL11.GL_BLEND);
+ GT_RenderUtil.applyStandardItemTransform(type);
+ GL11.glColor3f(1.0F, 1.0F, 1.0F);
+
+ IToolStats toolStats = item != null ? item.getToolStats(stack) : null;
+ if (toolStats != null) {
+ renderToolPart(type, stack, toolStats, false);
+ renderToolPart(type, stack, toolStats, true);
+
+ if ((type == ItemRenderType.INVENTORY)
+ && (GT_MetaGenerated_Tool.getPrimaryMaterial(stack) != Materials._NULL)) {
+ if (GT_Mod.gregtechproxy.mRenderItemDurabilityBar) {
+ IIconContainer iconContainer;
+ long damage = GT_MetaGenerated_Tool.getToolDamage(stack);
+ long maxDamage = GT_MetaGenerated_Tool.getToolMaxDamage(stack);
+ if (damage <= 0L) {
+ iconContainer = Textures.ItemIcons.DURABILITY_BAR[8];
+ } else if (damage >= maxDamage) {
+ iconContainer = Textures.ItemIcons.DURABILITY_BAR[0];
+ } else {
+ iconContainer = Textures.ItemIcons.DURABILITY_BAR[((int) Math
+ .max(0L, Math.min(7L, (maxDamage - damage) * 8L / maxDamage)))];
+ }
+ renderIcon(iconContainer);
+ }
+
+ if (GT_Mod.gregtechproxy.mRenderItemChargeBar) {
+ IIconContainer iconContainer;
+ Long[] stats = item.getElectricStats(stack);
+ if ((stats != null) && (stats[3] < 0L)) {
+ long tCharge = item.getRealCharge(stack);
+ if (tCharge <= 0L) {
+ iconContainer = Textures.ItemIcons.ENERGY_BAR[0];
+ } else if (tCharge >= stats[0]) {
+ iconContainer = Textures.ItemIcons.ENERGY_BAR[8];
+ } else {
+ iconContainer = Textures.ItemIcons.ENERGY_BAR[(7
+ - (int) Math.max(0L, Math.min(6L, (stats[0] - tCharge) * 7L / stats[0])))];
+ }
+ } else {
+ iconContainer = null;
+ }
+ renderIcon(iconContainer);
+ }
+ }
+ }
+ GL11.glDisable(GL11.GL_BLEND);
+ }
+
+ private void renderIcon(IIconContainer iconContainer) {
+ if (iconContainer != null) {
+ IIcon icon = iconContainer.getIcon();
+ IIcon overlay = iconContainer.getOverlayIcon();
+ if (icon != null) {
+ Minecraft.getMinecraft().renderEngine.bindTexture(iconContainer.getTextureFile());
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GT_RenderUtil.renderItemIcon(icon, 16.0D, 0.001D, 0.0F, 0.0F, -1.0F);
+ }
+ if (overlay != null) {
+ Minecraft.getMinecraft().renderEngine.bindTexture(iconContainer.getTextureFile());
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GT_RenderUtil.renderItemIcon(overlay, 16.0D, 0.001D, 0.0F, 0.0F, -1.0F);
+ }
+ }
+ }
+
+ private static void renderToolPart(ItemRenderType type, ItemStack stack, IToolStats toolStats, boolean isToolHead) {
+ IIconContainer iconContainer = toolStats.getIcon(isToolHead, stack);
+ if (iconContainer != null) {
+ IIcon icon = iconContainer.getIcon();
+ IIcon overlay = iconContainer.getOverlayIcon();
+ if (icon != null) {
+ Minecraft.getMinecraft().renderEngine.bindTexture(iconContainer.getTextureFile());
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ short[] modulation = toolStats.getRGBa(isToolHead, stack);
+ GL11.glColor3f(modulation[0] / 255.0F, modulation[1] / 255.0F, modulation[2] / 255.0F);
+ GT_RenderUtil.renderItem(type, icon);
+ GL11.glColor3f(1.0F, 1.0F, 1.0F);
+ }
+ if (overlay != null) {
+ Minecraft.getMinecraft().renderEngine.bindTexture(iconContainer.getTextureFile());
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GT_RenderUtil.renderItem(type, overlay);
+ }
+ }
+ }
+}
diff --git a/src/main/java/gregtech/common/render/GT_MultiTexture.java b/src/main/java/gregtech/common/render/GT_MultiTexture.java
new file mode 100644
index 0000000000..d3cff271cb
--- /dev/null
+++ b/src/main/java/gregtech/common/render/GT_MultiTexture.java
@@ -0,0 +1,69 @@
+package gregtech.common.render;
+
+import net.minecraft.block.Block;
+import net.minecraft.client.renderer.RenderBlocks;
+
+import gregtech.GT_Mod;
+import gregtech.api.interfaces.ITexture;
+
+/**
+ * <p>
+ * Lets Multiple ITextures Render overlay over each other.<
+ * </p>
+ * <p>
+ * I should have done this much earlier...
+ * </p>
+ */
+public class GT_MultiTexture extends GT_TextureBase implements ITexture {
+
+ protected final ITexture[] mTextures;
+
+ public static GT_MultiTexture get(ITexture... aTextures) {
+ return GT_Mod.instance.isClientSide() ? new GT_MultiTexture(aTextures) : null;
+ }
+
+ protected GT_MultiTexture(ITexture... aTextures) {
+ mTextures = aTextures;
+ }
+
+ @Override
+ public void renderXPos(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ for (ITexture tTexture : mTextures)
+ if (tTexture != null && tTexture.isValidTexture()) tTexture.renderXPos(aRenderer, aBlock, aX, aY, aZ);
+ }
+
+ @Override
+ public void renderXNeg(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ for (ITexture tTexture : mTextures)
+ if (tTexture != null && tTexture.isValidTexture()) tTexture.renderXNeg(aRenderer, aBlock, aX, aY, aZ);
+ }
+
+ @Override
+ public void renderYPos(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ for (ITexture tTexture : mTextures)
+ if (tTexture != null && tTexture.isValidTexture()) tTexture.renderYPos(aRenderer, aBlock, aX, aY, aZ);
+ }
+
+ @Override
+ public void renderYNeg(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ for (ITexture tTexture : mTextures)
+ if (tTexture != null && tTexture.isValidTexture()) tTexture.renderYNeg(aRenderer, aBlock, aX, aY, aZ);
+ }
+
+ @Override
+ public void renderZPos(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ for (ITexture tTexture : mTextures)
+ if (tTexture != null && tTexture.isValidTexture()) tTexture.renderZPos(aRenderer, aBlock, aX, aY, aZ);
+ }
+
+ @Override
+ public void renderZNeg(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ for (ITexture tTexture : mTextures)
+ if (tTexture != null && tTexture.isValidTexture()) tTexture.renderZNeg(aRenderer, aBlock, aX, aY, aZ);
+ }
+
+ @Override
+ public boolean isValidTexture() {
+ return true;
+ }
+}
diff --git a/src/main/java/gregtech/common/render/GT_MultiTile_Renderer.java b/src/main/java/gregtech/common/render/GT_MultiTile_Renderer.java
new file mode 100644
index 0000000000..4d55979658
--- /dev/null
+++ b/src/main/java/gregtech/common/render/GT_MultiTile_Renderer.java
@@ -0,0 +1,181 @@
+package gregtech.common.render;
+
+import net.minecraft.block.Block;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.RenderBlocks;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.IBlockAccess;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import org.lwjgl.opengl.GL11;
+
+import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
+import cpw.mods.fml.client.registry.RenderingRegistry;
+import gregtech.GT_Mod;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.logic.ModelRenderLogic;
+import gregtech.api.logic.interfaces.ModelRenderLogicHost;
+import gregtech.api.multitileentity.MultiTileEntityBlockInternal;
+import gregtech.api.multitileentity.MultiTileEntityClassContainer;
+import gregtech.api.multitileentity.MultiTileEntityRegistry;
+import gregtech.api.multitileentity.interfaces.IMultiBlockController;
+import gregtech.api.multitileentity.multiblock.base.MultiBlockPart;
+
+public class GT_MultiTile_Renderer implements ISimpleBlockRenderingHandler {
+
+ private final int renderID;
+ public static GT_MultiTile_Renderer INSTANCE;
+
+ public GT_MultiTile_Renderer() {
+ this.renderID = RenderingRegistry.getNextAvailableRenderId();
+ INSTANCE = this;
+ RenderingRegistry.registerBlockHandler(this);
+ }
+
+ @Override
+ public void renderInventoryBlock(Block block, int metadata, int modelId, RenderBlocks renderer) {
+ if (!(block instanceof MultiTileEntityBlockInternal)) {
+ return;
+ }
+
+ GL11.glRotatef(90.0F, 0.0F, 1.0F, 0.0F);
+ GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
+
+ MultiTileEntityBlockInternal mteBlock = (MultiTileEntityBlockInternal) block;
+ MultiTileEntityRegistry registry = mteBlock.getRegistry();
+ if (registry == null) return;
+ MultiTileEntityClassContainer classContainer = registry.getClassContainer(metadata);
+ if (classContainer == null) return;
+ renderer.setRenderBoundsFromBlock(mteBlock);
+
+ for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) {
+ ITexture texture = classContainer.mCanonicalTileEntity.getTexture(side);
+ if (texture == null) continue;
+ switch (side) {
+ case DOWN -> renderYNegative(null, renderer, 0, 0, 0, block, texture, side);
+ case UP -> renderYPositive(null, renderer, 0, 0, 0, block, texture, side);
+ case WEST -> renderXNegative(null, renderer, 0, 0, 0, block, texture, side);
+ case EAST -> renderXPositive(null, renderer, 0, 0, 0, block, texture, side);
+ case NORTH -> renderZNegative(null, renderer, 0, 0, 0, block, texture, side);
+ case SOUTH -> renderZPositive(null, renderer, 0, 0, 0, block, texture, side);
+ default -> {
+ // Do nothing
+ }
+ }
+ }
+
+ GL11.glTranslatef(0.5F, 0.5F, 0.5F);
+ }
+
+ @Override
+ public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId,
+ RenderBlocks renderer) {
+ TileEntity entity = world.getTileEntity(x, y, z);
+ if (entity == null) {
+ return false;
+ }
+
+ renderer.enableAO = Minecraft.isAmbientOcclusionEnabled() && GT_Mod.gregtechproxy.mRenderTileAmbientOcclusion;
+ renderer.useInventoryTint = false;
+
+ if (entity instanceof ModelRenderLogicHost modelEntity && modelEntity.shouldRenderModel()) {
+ ModelRenderLogic renderLogic = modelEntity.getRenderLogic();
+ return true;
+ }
+
+ if (!(entity instanceof MultiTileBasicRender)) {
+ return false;
+ }
+
+ if (entity instanceof MultiBlockPart) {
+ IMultiBlockController controller = ((MultiBlockPart) entity).getTarget(false);
+ if (controller instanceof ModelRenderLogicHost && ((ModelRenderLogicHost) controller).shouldRenderModel()) {
+ return false;
+ }
+ }
+
+ MultiTileBasicRender renderedEntity = (MultiTileBasicRender) entity;
+
+ for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) {
+ ITexture texture = renderedEntity.getTexture(side);
+ if (texture == null) continue;
+ switch (side) {
+ case DOWN -> renderYNegative(world, renderer, x, y, z, block, texture, side);
+ case UP -> renderYPositive(world, renderer, x, y, z, block, texture, side);
+ case WEST -> renderXNegative(world, renderer, x, y, z, block, texture, side);
+ case EAST -> renderXPositive(world, renderer, x, y, z, block, texture, side);
+ case NORTH -> renderZNegative(world, renderer, x, y, z, block, texture, side);
+ case SOUTH -> renderZPositive(world, renderer, x, y, z, block, texture, side);
+ default -> {
+ // Do nothing
+ }
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean shouldRender3DInInventory(int modelId) {
+ return true;
+ }
+
+ @Override
+ public int getRenderId() {
+ return renderID;
+ }
+
+ private static void renderYNegative(IBlockAccess world, RenderBlocks renderer, int x, int y, int z, Block block,
+ ITexture texture, ForgeDirection side) {
+ if (world != null) {
+ if (!block.shouldSideBeRendered(world, x, y - 1, z, side.ordinal())) return;
+ Tessellator.instance.setBrightness(block.getMixedBrightnessForBlock(world, x, y - 1, z));
+ }
+ texture.renderYNeg(renderer, block, x, y, z);
+ }
+
+ private static void renderZNegative(IBlockAccess world, RenderBlocks renderer, int x, int y, int z, Block block,
+ ITexture texture, ForgeDirection side) {
+ if (world != null) {
+ if (!block.shouldSideBeRendered(world, x, y, z - 1, side.ordinal())) return;
+ Tessellator.instance.setBrightness(block.getMixedBrightnessForBlock(world, x, y, z - 1));
+ }
+ texture.renderZNeg(renderer, block, x, y, z);
+ }
+
+ private static void renderXNegative(IBlockAccess world, RenderBlocks renderer, int x, int y, int z, Block block,
+ ITexture texture, ForgeDirection side) {
+ if (world != null) {
+ if (!block.shouldSideBeRendered(world, x - 1, y, z, side.ordinal())) return;
+ Tessellator.instance.setBrightness(block.getMixedBrightnessForBlock(world, x - 1, y, z));
+ }
+ texture.renderXNeg(renderer, block, x, y, z);
+ }
+
+ private static void renderYPositive(IBlockAccess world, RenderBlocks renderer, int x, int y, int z, Block block,
+ ITexture texture, ForgeDirection side) {
+ if (world != null) {
+ if (!block.shouldSideBeRendered(world, x, y + 1, z, side.ordinal())) return;
+ Tessellator.instance.setBrightness(block.getMixedBrightnessForBlock(world, x, y + 1, z));
+ }
+ texture.renderYPos(renderer, block, x, y, z);
+ }
+
+ private static void renderXPositive(IBlockAccess world, RenderBlocks renderer, int x, int y, int z, Block block,
+ ITexture texture, ForgeDirection side) {
+ if (world != null) {
+ if (!block.shouldSideBeRendered(world, x + 1, y, z, side.ordinal())) return;
+ Tessellator.instance.setBrightness(block.getMixedBrightnessForBlock(world, x + 1, y, z));
+ }
+ texture.renderXPos(renderer, block, x, y, z);
+ }
+
+ private static void renderZPositive(IBlockAccess world, RenderBlocks renderer, int x, int y, int z, Block block,
+ ITexture texture, ForgeDirection side) {
+ if (world != null) {
+ if (!block.shouldSideBeRendered(world, x, y, z + 1, side.ordinal())) return;
+ Tessellator.instance.setBrightness(block.getMixedBrightnessForBlock(world, x, y, z + 1));
+ }
+ texture.renderZPos(renderer, block, x, y, z);
+ }
+}
diff --git a/src/main/java/gregtech/common/render/GT_PollutionRenderer.java b/src/main/java/gregtech/common/render/GT_PollutionRenderer.java
new file mode 100644
index 0000000000..ee87b2b5d1
--- /dev/null
+++ b/src/main/java/gregtech/common/render/GT_PollutionRenderer.java
@@ -0,0 +1,251 @@
+package gregtech.common.render;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.material.Material;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.entity.EntityClientPlayerMP;
+import net.minecraft.client.particle.EntityFX;
+import net.minecraft.client.renderer.OpenGlHelper;
+import net.minecraft.potion.Potion;
+import net.minecraft.util.MathHelper;
+import net.minecraft.world.ChunkCoordIntPair;
+import net.minecraft.world.World;
+import net.minecraftforge.client.event.EntityViewRenderEvent;
+import net.minecraftforge.event.world.WorldEvent;
+
+import org.lwjgl.opengl.GL11;
+
+import cpw.mods.fml.common.FMLCommonHandler;
+import cpw.mods.fml.common.eventhandler.EventPriority;
+import cpw.mods.fml.common.eventhandler.SubscribeEvent;
+import cpw.mods.fml.common.gameevent.TickEvent;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import gregtech.GT_Mod;
+import gregtech.common.entities.GT_EntityFXPollution;
+import gregtech.common.misc.GT_ClientPollutionMap;
+
+@SideOnly(Side.CLIENT)
+public class GT_PollutionRenderer {
+
+ private static GT_ClientPollutionMap pollutionMap;
+ private static int playerPollution = 0;
+
+ private static final boolean DEBUG = false;
+
+ // PARTICLES_POLLUTION_START + PARTICLES_POLLUTION_END -> Max Particles
+ private static final int PARTICLES_MAX_NUM = 100;
+ private static final int PARTICLES_POLLUTION_START = 400000;
+ private static final int PARTICLES_POLLUTION_END = 3500000;
+
+ private static final int FOG_START_AT_POLLUTION = 400000;
+ private static final int FOG_MAX_AT_POLLUTION = 7000000;
+ // jump from linear to exponential fog. x*FOG_MAX_AT_POLLUTION+FOG_START_AT_POLLUTION
+ private static final double FOG_START_EXP_RATIO = 0.02D;
+
+ private static final float[] fogColor = { 0.3f, 0.25f, 0.1f };
+ private static final short[] grassColor = { 230, 180, 40 };
+ private static final short[] leavesColor = { 160, 80, 15 };
+ private static final short[] liquidColor = { 160, 200, 10 };
+ private static final short[] foliageColor = { 160, 80, 15 };
+
+ // TODO need to soft update some blocks, grass and leaves does more often than liquid it looks like.
+
+ public GT_PollutionRenderer() {
+ pollutionMap = new GT_ClientPollutionMap();
+ }
+
+ public void preLoad() {
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.register(this);
+ FMLCommonHandler.instance()
+ .bus()
+ .register(this);
+ }
+
+ public void processPacket(ChunkCoordIntPair chunk, int pollution) {
+ pollutionMap.addChunkPollution(chunk.chunkXPos, chunk.chunkZPos, pollution);
+ }
+
+ @SubscribeEvent(priority = EventPriority.HIGH)
+ public void enteredWorld(WorldEvent.Load event) {
+ EntityClientPlayerMP p = Minecraft.getMinecraft().thePlayer;
+ if (!event.world.isRemote || p == null) return;
+ pollutionMap.reset();
+ }
+
+ private static int color(int color, int pollution, int low, float high, short[] colors) {
+ if (pollution < low) return color;
+
+ int r = (color >> 16) & 0xFF;
+ int g = (color >> 8) & 0xFF;
+ int b = color & 0xFF;
+ float p = (pollution - low) / high;
+ if (p > 1) p = 1;
+ float pi = 1 - p;
+
+ r = ((int) (r * pi + p * colors[0])) & 0xFF;
+ g = ((int) (g * pi + p * colors[1])) & 0xFF;
+ b = ((int) (b * pi + p * colors[2])) & 0xFF;
+
+ return (r & 0xFF) << 16 | (g & 0xFF) << 8 | b & 0xFF;
+ }
+
+ // Methods for hodgepodge to color grass / foliage blocks etc.
+ public static int colorGrass(int oColor, int x, int z) {
+ return color(oColor, pollutionMap.getPollution(x, z) / 1000, 350, 600, grassColor);
+ }
+
+ public static int colorLeaves(int oColor, int x, int z) {
+ return color(oColor, pollutionMap.getPollution(x, z) / 1000, 300, 500, leavesColor);
+ }
+
+ public static int colorLiquid(int oColor, int x, int z) {
+ return color(oColor, pollutionMap.getPollution(x, z) / 1000, 300, 500, liquidColor);
+ }
+
+ public static int colorFoliage(int oColor, int x, int z) {
+ return color(oColor, pollutionMap.getPollution(x, z) / 1000, 300, 500, foliageColor);
+ }
+
+ public static int getKnownPollution(int x, int z) {
+ return pollutionMap.getPollution(x, z);
+ }
+
+ @SubscribeEvent(priority = EventPriority.LOW)
+ public void manipulateColor(EntityViewRenderEvent.FogColors event) {
+ if (!DEBUG && Minecraft.getMinecraft().thePlayer.capabilities.isCreativeMode) return;
+
+ if (event.block.getMaterial() == Material.water || event.block.getMaterial() == Material.lava) return;
+
+ float x = fogIntensityLastTick > 1 ? 1F : (float) fogIntensityLastTick;
+ float xi = 1 - x;
+
+ event.red = xi * event.red + x * fogColor[0];
+ event.green = xi * event.green + x * fogColor[1];
+ event.blue = xi * event.blue + x * fogColor[2];
+ }
+
+ private static final int END_MAX_DISTANCE = 192 - 1;
+ private static double fogIntensityLastTick = 0;
+
+ @SubscribeEvent(priority = EventPriority.LOWEST)
+ public void renderGTPollutionFog(EntityViewRenderEvent.RenderFogEvent event) {
+ if (!GT_Mod.gregtechproxy.mRenderPollutionFog) return;
+
+ if ((!DEBUG && Minecraft.getMinecraft().thePlayer.capabilities.isCreativeMode)
+ || (fogIntensityLastTick <= 0 && fogIntensityLastTick >= FOG_START_EXP_RATIO)) return;
+
+ if (event.fogMode == 0) {
+ double v = 1 - fogIntensityLastTick / FOG_START_EXP_RATIO;
+ // trying to smooth out jump from linear to exponential
+ GL11.glFogi(GL11.GL_FOG_MODE, GL11.GL_LINEAR);
+ GL11.glFogf(GL11.GL_FOG_START, (float) ((END_MAX_DISTANCE - 20) * 0.75F * v + 20));
+ GL11.glFogf(GL11.GL_FOG_END, (float) (END_MAX_DISTANCE * (0.75F + v * 0.25F)));
+ }
+ // else if ( event.fogMode < 0) { }
+ }
+
+ @SubscribeEvent(priority = EventPriority.LOWEST)
+ public void renderGTPollutionFog(EntityViewRenderEvent.FogDensity event) {
+ if (!GT_Mod.gregtechproxy.mRenderPollutionFog) return;
+
+ if (!DEBUG && Minecraft.getMinecraft().thePlayer.capabilities.isCreativeMode) return;
+
+ if (event.entity.isPotionActive(Potion.blindness) || (fogIntensityLastTick < FOG_START_EXP_RATIO)
+ || event.block.getMaterial() == Material.water
+ || event.block.getMaterial() == Material.lava) return;
+
+ GL11.glFogi(GL11.GL_FOG_MODE, GL11.GL_EXP2);
+ event.density = (float) Math.pow(fogIntensityLastTick - FOG_START_EXP_RATIO, .75F) / 5 + 0.01F;
+ event.setCanceled(true);
+ }
+
+ private double lastUpdate = 0;
+
+ @SubscribeEvent(priority = EventPriority.HIGHEST)
+ public void onRenderTick(TickEvent.RenderTickEvent event) {
+ Minecraft mc = Minecraft.getMinecraft();
+ if (mc == null) return;
+ EntityClientPlayerMP player = mc.thePlayer;
+ if (player == null) return;
+
+ if (event.phase == TickEvent.Phase.START) {
+ if (event.renderTickTime < lastUpdate) lastUpdate = lastUpdate - 1;
+ float step = (float) ((event.renderTickTime - lastUpdate) / 50);
+ lastUpdate = event.renderTickTime;
+
+ float fogIntensity = (playerPollution - FOG_START_AT_POLLUTION) / (float) FOG_MAX_AT_POLLUTION;
+ if (fogIntensity > 1) fogIntensity = 1;
+ else if (fogIntensity < 0) fogIntensity = 0;
+
+ double e = fogIntensity - fogIntensityLastTick;
+ if (e != 0) {
+ if (e > 0.2) e = 0.2D;
+ else if (e < -0.5) e = -0.5D;
+
+ if (e > 0.001D || e < -0.001D) fogIntensityLastTick += step * e;
+ else fogIntensityLastTick = fogIntensity;
+ }
+ } else if (DEBUG) {
+ drawPollution("Intensity: " + (fogIntensityLastTick * 10000), 0);
+ drawPollution(
+ "Pollution: " + pollutionMap.getPollution(
+ Minecraft.getMinecraft().thePlayer.lastTickPosX,
+ Minecraft.getMinecraft().thePlayer.lastTickPosZ),
+ 20);
+ drawPollution(
+ "Density: "
+ + ((float) (Math.pow(fogIntensityLastTick - FOG_START_EXP_RATIO, .75F) / 5 + 0.01F) * 10000),
+ 40);
+ }
+ }
+
+ // Adding dirt particles in the air
+ @SubscribeEvent(priority = EventPriority.HIGHEST)
+ public void onClientTick(TickEvent.ClientTickEvent event) {
+ if (!GT_Mod.gregtechproxy.mRenderDirtParticles) return;
+ Minecraft mc = Minecraft.getMinecraft();
+ if (mc == null) return;
+ EntityClientPlayerMP player = mc.thePlayer;
+ if (player == null || (player.capabilities.isCreativeMode && !DEBUG)) return;
+
+ World w = player.worldObj;
+ playerPollution = pollutionMap.getPollution(player.lastTickPosX, player.lastTickPosZ);
+
+ float intensity = ((float) playerPollution - PARTICLES_POLLUTION_START) / PARTICLES_POLLUTION_END;
+ if (intensity < 0) return;
+ else if (intensity > 1) intensity = 1;
+ else intensity *= intensity;
+
+ int x = MathHelper.floor_double(player.posX);
+ int y = MathHelper.floor_double(player.posY);
+ int z = MathHelper.floor_double(player.posZ);
+
+ int numParticles = Math.round(intensity * PARTICLES_MAX_NUM);
+
+ for (int l = 0; l < numParticles; ++l) {
+ int i1 = x + w.rand.nextInt(16) - w.rand.nextInt(16);
+ int j1 = y + w.rand.nextInt(16) - w.rand.nextInt(16);
+ int k1 = z + w.rand.nextInt(16) - w.rand.nextInt(16);
+ Block block = w.getBlock(i1, j1, k1);
+
+ if (block.getMaterial() == Material.air) {
+ EntityFX fx = new GT_EntityFXPollution(
+ w,
+ (float) i1 + w.rand.nextFloat(),
+ (float) j1 + w.rand.nextFloat(),
+ (float) k1 + w.rand.nextFloat());
+ mc.effectRenderer.addEffect(fx);
+ }
+ }
+ }
+
+ private void drawPollution(String text, int off) {
+ GL11.glPushMatrix();
+ GL11.glEnable(GL11.GL_BLEND);
+ OpenGlHelper.glBlendFunc(770, 771, 1, 0);
+ Minecraft.getMinecraft().fontRenderer.drawStringWithShadow(text, 0, off, 0xFFFFFFFF);
+ GL11.glDisable(GL11.GL_BLEND);
+ GL11.glPopMatrix();
+ }
+}
diff --git a/src/main/java/gregtech/common/render/GT_RenderDrone.java b/src/main/java/gregtech/common/render/GT_RenderDrone.java
new file mode 100644
index 0000000000..af1336a219
--- /dev/null
+++ b/src/main/java/gregtech/common/render/GT_RenderDrone.java
@@ -0,0 +1,93 @@
+package gregtech.common.render;
+
+import static gregtech.api.enums.Mods.GregTech;
+
+import net.minecraft.client.renderer.OpenGlHelper;
+import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.client.model.AdvancedModelLoader;
+import net.minecraftforge.client.model.IModelCustom;
+
+import org.lwjgl.opengl.GL11;
+
+import cpw.mods.fml.client.registry.ClientRegistry;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import gregtech.common.tileentities.render.TileDrone;
+
+@SideOnly(Side.CLIENT)
+public class GT_RenderDrone extends TileEntitySpecialRenderer {
+
+ private static final ResourceLocation DroneTexture = new ResourceLocation(GregTech.ID, "textures/model/drone.png");
+ private static final IModelCustom Drone = AdvancedModelLoader
+ .loadModel(new ResourceLocation(GregTech.ID, "textures/model/drone.obj"));
+
+ public GT_RenderDrone() {
+ ClientRegistry.bindTileEntitySpecialRenderer(TileDrone.class, this);
+ }
+
+ @Override
+ public void renderTileEntityAt(TileEntity tile, double x, double y, double z, float timeSinceLastTick) {
+ if (!(tile instanceof TileDrone drone)) return;
+ final float size = 1.0f;
+ GL11.glPushMatrix();
+ GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5);
+ renderDrone(size);
+ renderBlade(drone, size);
+ GL11.glPopMatrix();
+ }
+
+ private void renderDrone(double size) {
+ GL11.glDisable(GL11.GL_LIGHTING);
+ GL11.glDisable(GL11.GL_CULL_FACE);
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ this.bindTexture(DroneTexture);
+ GL11.glScaled(size, size, size);
+ OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
+ Drone.renderOnly("drone", "box", "main");
+ GL11.glDisable(GL11.GL_BLEND);
+ GL11.glDepthMask(true);
+ GL11.glEnable(GL11.GL_CULL_FACE);
+ GL11.glEnable(GL11.GL_LIGHTING);
+ }
+
+ private void renderBlade(TileDrone drone, double size) {
+ GL11.glDisable(GL11.GL_LIGHTING);
+ GL11.glDisable(GL11.GL_CULL_FACE);
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ this.bindTexture(DroneTexture);
+ GL11.glScaled(size, size, size);
+ OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
+ GL11.glPushMatrix();
+ GL11.glTranslated(-0.7d * size, -1 * size, -0.7 * size);
+ GL11.glRotated(drone.rotation, 0, 1, 0);
+ GL11.glTranslated(0.7d * size, 1 * size, 0.7 * size);
+ Drone.renderOnly("blade2");
+ GL11.glPopMatrix();
+ GL11.glPushMatrix();
+ GL11.glTranslated(-0.7d * size, -1 * size, 0.7 * size);
+ GL11.glRotated(drone.rotation, 0, 1, 0);
+ GL11.glTranslated(0.7d * size, 1 * size, -0.7 * size);
+ Drone.renderOnly("blade3");
+ GL11.glPopMatrix();
+ GL11.glPushMatrix();
+ GL11.glTranslated(0.7d * size, -1 * size, -0.7 * size);
+ GL11.glRotated(drone.rotation, 0, 1, 0);
+ GL11.glTranslated(-0.7d * size, 1 * size, 0.7 * size);
+ Drone.renderOnly("blade1");
+ GL11.glPopMatrix();
+ GL11.glPushMatrix();
+ GL11.glTranslated(0.7d * size, -1 * size, 0.7 * size);
+ GL11.glRotated(drone.rotation, 0, 1, 0);
+ GL11.glTranslated(-0.7d * size, 1 * size, -0.7 * size);
+ Drone.renderOnly("blade4");
+ GL11.glPopMatrix();
+ GL11.glDisable(GL11.GL_BLEND);
+ GL11.glDepthMask(true);
+ GL11.glEnable(GL11.GL_CULL_FACE);
+ GL11.glEnable(GL11.GL_LIGHTING);
+ }
+}
diff --git a/src/main/java/gregtech/common/render/GT_RenderUtil.java b/src/main/java/gregtech/common/render/GT_RenderUtil.java
new file mode 100644
index 0000000000..68195513fe
--- /dev/null
+++ b/src/main/java/gregtech/common/render/GT_RenderUtil.java
@@ -0,0 +1,141 @@
+package gregtech.common.render;
+
+import net.minecraft.block.Block;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.ItemRenderer;
+import net.minecraft.client.renderer.RenderBlocks;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.client.renderer.entity.RenderItem;
+import net.minecraft.client.renderer.entity.RenderManager;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.IIcon;
+import net.minecraftforge.client.IItemRenderer;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import org.lwjgl.opengl.GL11;
+
+import gregtech.api.interfaces.IGT_ItemWithMaterialRenderer;
+
+public class GT_RenderUtil {
+
+ public static void colorGTItem(ItemStack aStack) {
+ if (aStack.getItem() instanceof IGT_ItemWithMaterialRenderer aItem) {
+
+ short[] tModulation = aItem.getRGBa(aStack);
+ GL11.glColor4f(tModulation[0] / 255.0F, tModulation[1] / 255.0F, tModulation[2] / 255.0F, 255.0f);
+ } else {
+ System.out.println("WARNING: " + aStack.getDisplayName() + " does not have an associated GT colour.");
+ }
+ }
+
+ public static void renderBlockIcon(RenderBlocks aRenderer, Block aBlock, double aX, double aY, double aZ,
+ IIcon aIcon, ForgeDirection side) {
+ switch (side) {
+ case DOWN -> aRenderer.renderFaceYNeg(aBlock, aX, aY, aZ, aIcon);
+ case UP -> aRenderer.renderFaceYPos(aBlock, aX, aY, aZ, aIcon);
+ case NORTH -> aRenderer.renderFaceZNeg(aBlock, aX, aY, aZ, aIcon);
+ case SOUTH -> aRenderer.renderFaceZPos(aBlock, aX, aY, aZ, aIcon);
+ case WEST -> aRenderer.renderFaceXNeg(aBlock, aX, aY, aZ, aIcon);
+ case EAST -> aRenderer.renderFaceXPos(aBlock, aX, aY, aZ, aIcon);
+ }
+ }
+
+ public static void renderItemIcon(IIcon icon, double size, double z, float nx, float ny, float nz) {
+ renderItemIcon(icon, 0.0D, 0.0D, size, size, z, nx, ny, nz);
+ }
+
+ public static void renderItemIcon(IIcon icon, double xStart, double yStart, double xEnd, double yEnd, double z,
+ float nx, float ny, float nz) {
+ if (icon == null) {
+ return;
+ }
+ Tessellator.instance.startDrawingQuads();
+ Tessellator.instance.setNormal(nx, ny, nz);
+ if (nz > 0.0F) {
+ Tessellator.instance.addVertexWithUV(xStart, yStart, z, icon.getMinU(), icon.getMinV());
+ Tessellator.instance.addVertexWithUV(xEnd, yStart, z, icon.getMaxU(), icon.getMinV());
+ Tessellator.instance.addVertexWithUV(xEnd, yEnd, z, icon.getMaxU(), icon.getMaxV());
+ Tessellator.instance.addVertexWithUV(xStart, yEnd, z, icon.getMinU(), icon.getMaxV());
+ } else {
+ Tessellator.instance.addVertexWithUV(xStart, yEnd, z, icon.getMinU(), icon.getMaxV());
+ Tessellator.instance.addVertexWithUV(xEnd, yEnd, z, icon.getMaxU(), icon.getMaxV());
+ Tessellator.instance.addVertexWithUV(xEnd, yStart, z, icon.getMaxU(), icon.getMinV());
+ Tessellator.instance.addVertexWithUV(xStart, yStart, z, icon.getMinU(), icon.getMinV());
+ }
+ Tessellator.instance.draw();
+ }
+
+ @SuppressWarnings("RedundantLabeledSwitchRuleCodeBlock")
+ public static void renderItem(IItemRenderer.ItemRenderType type, IIcon icon) {
+ Tessellator tessellator = Tessellator.instance;
+ float maxU = icon.getMaxU();
+ float minV = icon.getMinV();
+ float minU = icon.getMinU();
+ float maxV = icon.getMaxV();
+
+ switch (type) {
+ case ENTITY -> {
+ if (Minecraft.getMinecraft().gameSettings.fancyGraphics) {
+ ItemRenderer.renderItemIn2D(
+ tessellator,
+ maxU,
+ minV,
+ minU,
+ maxV,
+ icon.getIconWidth(),
+ icon.getIconHeight(),
+ 0.0625F);
+ } else {
+ GL11.glPushMatrix();
+
+ if (!RenderItem.renderInFrame) {
+ GL11.glRotatef(180.0F - RenderManager.instance.playerViewY, 0.0F, 1.0F, 0.0F);
+ }
+
+ tessellator.startDrawingQuads();
+ tessellator.setNormal(0.0F, 1.0F, 0.0F);
+ tessellator.addVertexWithUV(0.0F - 0.5F, 0.0F - 0.25F, 0.0D, minU, maxV);
+ tessellator.addVertexWithUV(1.0F - 0.5F, 0.0F - 0.25F, 0.0D, maxU, maxV);
+ tessellator.addVertexWithUV(1.0F - 0.5F, 1.0F - 0.25F, 0.0D, maxU, minV);
+ tessellator.addVertexWithUV(0.0F - 0.5F, 1.0F - 0.25F, 0.0D, minU, minV);
+ tessellator.draw();
+
+ GL11.glPopMatrix();
+ }
+ }
+ case EQUIPPED, EQUIPPED_FIRST_PERSON -> {
+ ItemRenderer.renderItemIn2D(
+ tessellator,
+ maxU,
+ minV,
+ minU,
+ maxV,
+ icon.getIconWidth(),
+ icon.getIconHeight(),
+ 0.0625F);
+ }
+ case INVENTORY -> {
+ renderItemIcon(icon, 16.0D, 0.001, 0.0F, 0.0F, -1.0F);
+ }
+ default -> {}
+ }
+ }
+
+ public static void applyStandardItemTransform(IItemRenderer.ItemRenderType type) {
+ if (type == IItemRenderer.ItemRenderType.ENTITY) {
+ if (RenderItem.renderInFrame) {
+ // Magic numbers calculated from vanilla code
+ GL11.glScalef(1.025641F, 1.025641F, 1.025641F);
+ GL11.glTranslatef(0.0F, -0.05F, 0.0F);
+ }
+
+ if (Minecraft.getMinecraft().gameSettings.fancyGraphics) {
+ if (RenderItem.renderInFrame) {
+ GL11.glRotatef(180.0F, 0.0F, 1.0F, 0.0F);
+ }
+ // Magic numbers calculated from vanilla code
+ GL11.glTranslatef(-0.5F, -0.25F, 0.0421875F);
+ }
+ }
+ }
+}
diff --git a/src/main/java/gregtech/common/render/GT_RenderedTexture.java b/src/main/java/gregtech/common/render/GT_RenderedTexture.java
new file mode 100644
index 0000000000..afaf3b290c
--- /dev/null
+++ b/src/main/java/gregtech/common/render/GT_RenderedTexture.java
@@ -0,0 +1,395 @@
+package gregtech.common.render;
+
+import static gregtech.api.util.LightingHelper.MAX_BRIGHTNESS;
+
+import net.minecraft.block.Block;
+import net.minecraft.client.renderer.RenderBlocks;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.init.Blocks;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.IIcon;
+import net.minecraft.world.World;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import com.gtnewhorizon.structurelib.alignment.IAlignment;
+import com.gtnewhorizon.structurelib.alignment.IAlignmentProvider;
+import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing;
+import com.gtnewhorizon.structurelib.alignment.enumerable.Flip;
+import com.gtnewhorizon.structurelib.alignment.enumerable.Rotation;
+
+import gregtech.GT_Mod;
+import gregtech.api.interfaces.IColorModulationContainer;
+import gregtech.api.interfaces.IIconContainer;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.util.LightingHelper;
+
+public class GT_RenderedTexture extends GT_TextureBase implements ITexture, IColorModulationContainer {
+
+ protected final IIconContainer mIconContainer;
+ private final short[] mRGBa;
+ private final boolean glow;
+ private final boolean stdOrient;
+ private final boolean useExtFacing;
+
+ protected GT_RenderedTexture(IIconContainer aIcon, short[] aRGBa, boolean allowAlpha, boolean glow,
+ boolean stdOrient, boolean extFacing) {
+ if (aRGBa.length != 4) throw new IllegalArgumentException("RGBa doesn't have 4 Values @ GT_RenderedTexture");
+ mIconContainer = aIcon;
+ mRGBa = aRGBa;
+ this.glow = glow;
+ this.stdOrient = stdOrient;
+ this.useExtFacing = extFacing;
+ }
+
+ @Override
+ public boolean isOldTexture() {
+ return false;
+ }
+
+ @Override
+ public void renderXPos(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ startDrawingQuads(aRenderer, 1.0f, 0.0f, 0.0f);
+ final boolean enableAO = aRenderer.enableAO;
+ final LightingHelper lighting = new LightingHelper(aRenderer);
+ if (glow) {
+ if (!GT_Mod.gregtechproxy.mRenderGlowTextures) {
+ draw(aRenderer);
+ return;
+ }
+ aRenderer.enableAO = false;
+ lighting.setLightnessOverride(1.0F);
+ if (enableAO) lighting.setBrightnessOverride(MAX_BRIGHTNESS);
+ }
+ lighting.setupLightingXPos(aBlock, aX, aY, aZ)
+ .setupColor(ForgeDirection.EAST, mRGBa);
+ final ExtendedFacing rotation = getExtendedFacing(aX, aY, aZ);
+ renderFaceXPos(aRenderer, aX, aY, aZ, mIconContainer.getIcon(), rotation);
+ if (mIconContainer.getOverlayIcon() != null) {
+ lighting.setupColor(ForgeDirection.EAST, 0xffffff);
+ renderFaceXPos(aRenderer, aX, aY, aZ, mIconContainer.getOverlayIcon(), rotation);
+ }
+ aRenderer.enableAO = enableAO;
+ draw(aRenderer);
+ }
+
+ @Override
+ public void renderXNeg(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ startDrawingQuads(aRenderer, -1.0f, 0.0f, 0.0f);
+ final boolean enableAO = aRenderer.enableAO;
+ final LightingHelper lighting = new LightingHelper(aRenderer);
+ if (glow) {
+ if (!GT_Mod.gregtechproxy.mRenderGlowTextures) {
+ draw(aRenderer);
+ return;
+ }
+ aRenderer.enableAO = false;
+ lighting.setLightnessOverride(1.0F);
+ lighting.setBrightnessOverride(MAX_BRIGHTNESS);
+ }
+ lighting.setupLightingXNeg(aBlock, aX, aY, aZ)
+ .setupColor(ForgeDirection.WEST, mRGBa);
+ final ExtendedFacing rotation = getExtendedFacing(aX, aY, aZ);
+ renderFaceXNeg(aRenderer, aX, aY, aZ, mIconContainer.getIcon(), rotation);
+ if (mIconContainer.getOverlayIcon() != null) {
+ lighting.setupColor(ForgeDirection.WEST, 0xffffff);
+ renderFaceXNeg(aRenderer, aX, aY, aZ, mIconContainer.getOverlayIcon(), rotation);
+ }
+ aRenderer.enableAO = enableAO;
+ draw(aRenderer);
+ }
+
+ @Override
+ public void renderYPos(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ startDrawingQuads(aRenderer, 0.0f, 1.0f, 0.0f);
+ final boolean enableAO = aRenderer.enableAO;
+ final LightingHelper lighting = new LightingHelper(aRenderer);
+ if (glow) {
+ if (!GT_Mod.gregtechproxy.mRenderGlowTextures) {
+ draw(aRenderer);
+ return;
+ }
+ aRenderer.enableAO = false;
+ lighting.setLightnessOverride(1.0F);
+ lighting.setBrightnessOverride(MAX_BRIGHTNESS);
+ }
+ lighting.setupLightingYPos(aBlock, aX, aY, aZ)
+ .setupColor(ForgeDirection.UP, mRGBa);
+ final ExtendedFacing rotation = getExtendedFacing(aX, aY, aZ);
+ renderFaceYPos(aRenderer, aX, aY, aZ, mIconContainer.getIcon(), rotation);
+ if (mIconContainer.getOverlayIcon() != null) {
+ lighting.setupColor(ForgeDirection.UP, 0xffffff);
+ renderFaceYPos(aRenderer, aX, aY, aZ, mIconContainer.getOverlayIcon(), rotation);
+ }
+ aRenderer.enableAO = enableAO;
+ draw(aRenderer);
+ }
+
+ @Override
+ public void renderYNeg(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ startDrawingQuads(aRenderer, 0.0f, -1.0f, 0.0f);
+ final boolean enableAO = aRenderer.enableAO;
+ final LightingHelper lighting = new LightingHelper(aRenderer);
+ if (glow) {
+ if (!GT_Mod.gregtechproxy.mRenderGlowTextures) {
+ draw(aRenderer);
+ return;
+ }
+ aRenderer.enableAO = false;
+ lighting.setLightnessOverride(1.0F);
+ lighting.setBrightnessOverride(MAX_BRIGHTNESS);
+ }
+ lighting.setupLightingYNeg(aBlock, aX, aY, aZ)
+ .setupColor(ForgeDirection.DOWN, mRGBa);
+ final ExtendedFacing rotation = getExtendedFacing(aX, aY, aZ);
+ renderFaceYNeg(aRenderer, aX, aY, aZ, mIconContainer.getIcon(), rotation);
+ if (mIconContainer.getOverlayIcon() != null) {
+ Tessellator.instance.setColorRGBA(255, 255, 255, 255);
+ renderFaceYNeg(aRenderer, aX, aY, aZ, mIconContainer.getOverlayIcon(), rotation);
+ }
+ aRenderer.enableAO = enableAO;
+ draw(aRenderer);
+ }
+
+ @Override
+ public void renderZPos(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ startDrawingQuads(aRenderer, 0.0f, 0.0f, 1.0f);
+ final boolean enableAO = aRenderer.enableAO;
+ final LightingHelper lighting = new LightingHelper(aRenderer);
+ if (glow) {
+ if (!GT_Mod.gregtechproxy.mRenderGlowTextures) {
+ draw(aRenderer);
+ return;
+ }
+ aRenderer.enableAO = false;
+ lighting.setLightnessOverride(1.0F);
+ lighting.setBrightnessOverride(MAX_BRIGHTNESS);
+ }
+ lighting.setupLightingZPos(aBlock, aX, aY, aZ)
+ .setupColor(ForgeDirection.SOUTH, mRGBa);
+ final ExtendedFacing rotation = getExtendedFacing(aX, aY, aZ);
+ renderFaceZPos(aRenderer, aX, aY, aZ, mIconContainer.getIcon(), rotation);
+ if (mIconContainer.getOverlayIcon() != null) {
+ lighting.setupColor(ForgeDirection.SOUTH, 0xffffff);
+ renderFaceZPos(aRenderer, aX, aY, aZ, mIconContainer.getOverlayIcon(), rotation);
+ }
+ aRenderer.enableAO = enableAO;
+ draw(aRenderer);
+ }
+
+ @Override
+ public void renderZNeg(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ startDrawingQuads(aRenderer, 0.0f, 0.0f, -1.0f);
+ final boolean enableAO = aRenderer.enableAO;
+ final LightingHelper lighting = new LightingHelper(aRenderer);
+ if (glow) {
+ if (!GT_Mod.gregtechproxy.mRenderGlowTextures) {
+ draw(aRenderer);
+ return;
+ }
+ aRenderer.enableAO = false;
+ lighting.setLightnessOverride(1.0F);
+ lighting.setBrightnessOverride(MAX_BRIGHTNESS);
+ }
+ lighting.setupLightingZNeg(aBlock, aX, aY, aZ)
+ .setupColor(ForgeDirection.NORTH, mRGBa);
+ final ExtendedFacing rotation = getExtendedFacing(aX, aY, aZ);
+ renderFaceZNeg(aRenderer, aX, aY, aZ, mIconContainer.getIcon(), rotation);
+ if (mIconContainer.getOverlayIcon() != null) {
+ lighting.setupColor(ForgeDirection.NORTH, 0xffffff);
+ renderFaceZNeg(aRenderer, aX, aY, aZ, mIconContainer.getOverlayIcon(), rotation);
+ }
+ aRenderer.enableAO = enableAO;
+ draw(aRenderer);
+ }
+
+ @Override
+ public short[] getRGBA() {
+ return mRGBa;
+ }
+
+ @Override
+ public boolean isValidTexture() {
+ return mIconContainer != null;
+ }
+
+ /**
+ * Renders the given texture to the bottom face of the block. Args: block, x, y, z, texture
+ */
+ protected void renderFaceYNeg(RenderBlocks aRenderer, double x, double y, double z, IIcon icon,
+ ExtendedFacing extendedFacing) {
+
+ switch (useExtFacing ? extendedFacing.getRotation() : Rotation.NORMAL) {
+ case COUNTER_CLOCKWISE -> aRenderer.uvRotateBottom = 2;
+ case CLOCKWISE -> aRenderer.uvRotateBottom = 1;
+ case UPSIDE_DOWN -> aRenderer.uvRotateBottom = 3;
+ default -> aRenderer.uvRotateBottom = 0;
+ }
+
+ final Flip aFlip = extendedFacing.getFlip();
+ aRenderer.renderFaceYNeg(
+ Blocks.air,
+ x,
+ y,
+ z,
+ useExtFacing && GT_Mod.gregtechproxy.mRenderFlippedMachinesFlipped
+ ? new GT_IconFlipped(icon, aFlip.isHorizontallyFlipped() ^ !stdOrient, aFlip.isVerticallyFliped())
+ : new GT_IconFlipped(icon, !stdOrient, false));
+ aRenderer.uvRotateBottom = 0;
+ }
+
+ /**
+ * Renders the given texture to the top face of the block. Args: block, x, y, z, texture
+ */
+ protected void renderFaceYPos(RenderBlocks aRenderer, double x, double y, double z, IIcon icon,
+ ExtendedFacing extendedFacing) {
+
+ switch (useExtFacing ? extendedFacing.getRotation() : Rotation.NORMAL) {
+ case COUNTER_CLOCKWISE -> aRenderer.uvRotateTop = 2;
+ case CLOCKWISE -> aRenderer.uvRotateTop = 1;
+ case UPSIDE_DOWN -> aRenderer.uvRotateTop = 3;
+ default -> aRenderer.uvRotateTop = 0;
+ }
+
+ final Flip aFlip = extendedFacing.getFlip();
+ aRenderer.renderFaceYPos(
+ Blocks.air,
+ x,
+ y,
+ z,
+ useExtFacing && GT_Mod.gregtechproxy.mRenderFlippedMachinesFlipped
+ ? new GT_IconFlipped(icon, aFlip.isHorizontallyFlipped(), aFlip.isVerticallyFliped())
+ : icon);
+ aRenderer.uvRotateTop = 0;
+ }
+
+ /**
+ * Renders the given texture to the north (z-negative) face of the block. Args: block, x, y, z, texture
+ */
+ protected void renderFaceZNeg(RenderBlocks aRenderer, double x, double y, double z, IIcon icon,
+ ExtendedFacing extendedFacing) {
+ aRenderer.field_152631_f = true;
+ // **NOT A BUG**: aRenderer.uvRotateEast REALLY CONTROLS THE ROTATION OF THE NORTH SIDE
+ switch (useExtFacing ? extendedFacing.getRotation() : Rotation.NORMAL) {
+ case COUNTER_CLOCKWISE -> aRenderer.uvRotateEast = 2;
+ case CLOCKWISE -> aRenderer.uvRotateEast = 1;
+ case UPSIDE_DOWN -> aRenderer.uvRotateEast = 3;
+ default -> aRenderer.uvRotateEast = 0;
+ }
+
+ final Flip aFlip = extendedFacing.getFlip();
+ aRenderer.renderFaceZNeg(
+ Blocks.air,
+ x,
+ y,
+ z,
+ useExtFacing && GT_Mod.gregtechproxy.mRenderFlippedMachinesFlipped
+ ? new GT_IconFlipped(icon, aFlip.isHorizontallyFlipped(), aFlip.isVerticallyFliped())
+ : icon);
+ aRenderer.uvRotateEast = 0;
+ aRenderer.field_152631_f = false;
+ }
+
+ /**
+ * Renders the given texture to the south (z-positive) face of the block. Args: block, x, y, z, texture
+ */
+ protected void renderFaceZPos(RenderBlocks aRenderer, double x, double y, double z, IIcon icon,
+ ExtendedFacing extendedFacing) {
+ // **NOT A BUG**: aRenderer.uvRotateWest REALLY CONTROLS THE ROTATION OF THE SOUTH SIDE
+ switch (useExtFacing ? extendedFacing.getRotation() : Rotation.NORMAL) {
+ case COUNTER_CLOCKWISE -> aRenderer.uvRotateWest = 2;
+ case CLOCKWISE -> aRenderer.uvRotateWest = 1;
+ case UPSIDE_DOWN -> aRenderer.uvRotateWest = 3;
+ default -> aRenderer.uvRotateWest = 0;
+ }
+
+ final Flip aFlip = extendedFacing.getFlip();
+ aRenderer.renderFaceZPos(
+ Blocks.air,
+ x,
+ y,
+ z,
+ useExtFacing && GT_Mod.gregtechproxy.mRenderFlippedMachinesFlipped
+ ? new GT_IconFlipped(icon, aFlip.isHorizontallyFlipped(), aFlip.isVerticallyFliped())
+ : icon);
+ aRenderer.uvRotateWest = 0;
+ }
+
+ /**
+ * Renders the given texture to the west (x-negative) face of the block. Args: block, x, y, z, texture
+ */
+ protected void renderFaceXNeg(RenderBlocks aRenderer, double x, double y, double z, IIcon icon,
+ ExtendedFacing extendedFacing) {
+ // **NOT A BUG**: aRenderer.uvRotateNorth REALLY CONTROLS THE ROTATION OF THE WEST SIDE
+ switch (useExtFacing ? extendedFacing.getRotation() : Rotation.NORMAL) {
+ case COUNTER_CLOCKWISE -> aRenderer.uvRotateNorth = 2;
+ case CLOCKWISE -> aRenderer.uvRotateNorth = 1;
+ case UPSIDE_DOWN -> aRenderer.uvRotateNorth = 3;
+ default -> aRenderer.uvRotateNorth = 0;
+ }
+
+ final Flip aFlip = extendedFacing.getFlip();
+ aRenderer.renderFaceXNeg(
+ Blocks.air,
+ x,
+ y,
+ z,
+ useExtFacing && GT_Mod.gregtechproxy.mRenderFlippedMachinesFlipped
+ ? new GT_IconFlipped(icon, aFlip.isHorizontallyFlipped(), aFlip.isVerticallyFliped())
+ : icon);
+ aRenderer.uvRotateNorth = 0;
+ }
+
+ /**
+ * Renders the given texture to the east (x-positive) face of the block. Args: block, x, y, z, texture
+ */
+ protected void renderFaceXPos(RenderBlocks aRenderer, double x, double y, double z, IIcon icon,
+ ExtendedFacing extendedFacing) {
+ aRenderer.field_152631_f = true;
+ // **NOT A BUG**: aRenderer.uvRotateSouth REALLY CONTROLS THE ROTATION OF THE EAST SIDE
+ switch (useExtFacing ? extendedFacing.getRotation() : Rotation.NORMAL) {
+ case COUNTER_CLOCKWISE -> aRenderer.uvRotateSouth = 2;
+ case CLOCKWISE -> aRenderer.uvRotateSouth = 1;
+ case UPSIDE_DOWN -> aRenderer.uvRotateSouth = 3;
+ default -> aRenderer.uvRotateSouth = 0;
+ }
+
+ final Flip aFlip = extendedFacing.getFlip();
+ aRenderer.renderFaceXPos(
+ Blocks.air,
+ x,
+ y,
+ z,
+ useExtFacing && GT_Mod.gregtechproxy.mRenderFlippedMachinesFlipped
+ ? new GT_IconFlipped(icon, aFlip.isHorizontallyFlipped(), aFlip.isVerticallyFliped())
+ : icon);
+ aRenderer.uvRotateSouth = 0;
+ aRenderer.field_152631_f = false;
+ }
+
+ private ExtendedFacing getExtendedFacing(int x, int y, int z) {
+ if (stdOrient) return ExtendedFacing.DEFAULT;
+ final EntityPlayer player = GT_Mod.gregtechproxy.getThePlayer();
+ if (player == null) return ExtendedFacing.DEFAULT;
+ final World w = player.getEntityWorld();
+ if (w == null) return ExtendedFacing.DEFAULT;
+ final TileEntity te = w.getTileEntity(x, y, z);
+ IAlignment alignment = null;
+ if (te instanceof IGregTechTileEntity) {
+ final IMetaTileEntity meta = ((IGregTechTileEntity) te).getMetaTileEntity();
+ if (meta instanceof IAlignmentProvider) {
+ alignment = ((IAlignmentProvider) meta).getAlignment();
+ } else if (meta != null) {
+ return ExtendedFacing.of(
+ meta.getBaseMetaTileEntity()
+ .getFrontFacing());
+ }
+ } else if (te instanceof IAlignmentProvider) {
+ alignment = ((IAlignmentProvider) te).getAlignment();
+ }
+ if (alignment != null) return alignment.getExtendedFacing();
+ return ExtendedFacing.DEFAULT;
+ }
+}
diff --git a/src/main/java/gregtech/common/render/GT_Renderer_Block.java b/src/main/java/gregtech/common/render/GT_Renderer_Block.java
new file mode 100644
index 0000000000..da0d68d555
--- /dev/null
+++ b/src/main/java/gregtech/common/render/GT_Renderer_Block.java
@@ -0,0 +1,747 @@
+package gregtech.common.render;
+
+import static gregtech.api.enums.GT_Values.SIDE_DOWN;
+import static gregtech.api.enums.GT_Values.SIDE_EAST;
+import static gregtech.api.enums.GT_Values.SIDE_NORTH;
+import static gregtech.api.enums.GT_Values.SIDE_SOUTH;
+import static gregtech.api.enums.GT_Values.SIDE_UP;
+import static gregtech.api.enums.GT_Values.SIDE_WEST;
+import static gregtech.api.interfaces.metatileentity.IConnectable.CONNECTED_DOWN;
+import static gregtech.api.interfaces.metatileentity.IConnectable.CONNECTED_EAST;
+import static gregtech.api.interfaces.metatileentity.IConnectable.CONNECTED_NORTH;
+import static gregtech.api.interfaces.metatileentity.IConnectable.CONNECTED_SOUTH;
+import static gregtech.api.interfaces.metatileentity.IConnectable.CONNECTED_UP;
+import static gregtech.api.interfaces.metatileentity.IConnectable.CONNECTED_WEST;
+import static gregtech.api.interfaces.metatileentity.IConnectable.HAS_FRESHFOAM;
+import static gregtech.api.interfaces.metatileentity.IConnectable.HAS_HARDENEDFOAM;
+import static gregtech.api.interfaces.metatileentity.IConnectable.NO_CONNECTION;
+import static net.minecraftforge.common.util.ForgeDirection.DOWN;
+import static net.minecraftforge.common.util.ForgeDirection.EAST;
+import static net.minecraftforge.common.util.ForgeDirection.NORTH;
+import static net.minecraftforge.common.util.ForgeDirection.SOUTH;
+import static net.minecraftforge.common.util.ForgeDirection.UP;
+import static net.minecraftforge.common.util.ForgeDirection.VALID_DIRECTIONS;
+import static net.minecraftforge.common.util.ForgeDirection.WEST;
+
+import net.minecraft.block.Block;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.particle.EffectRenderer;
+import net.minecraft.client.particle.EntityDiggingFX;
+import net.minecraft.client.renderer.RenderBlocks;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.IBlockAccess;
+import net.minecraft.world.World;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import org.lwjgl.opengl.GL11;
+
+import com.gtnewhorizons.angelica.api.ThreadSafeISBRH;
+
+import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
+import cpw.mods.fml.client.registry.RenderingRegistry;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import gregtech.GT_Mod;
+import gregtech.api.GregTech_API;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.tileentity.IAllSidedTexturedTileEntity;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.interfaces.tileentity.IPipeRenderedTileEntity;
+import gregtech.api.interfaces.tileentity.ITexturedTileEntity;
+import gregtech.api.metatileentity.MetaPipeEntity;
+import gregtech.api.objects.XSTR;
+import gregtech.common.blocks.GT_Block_Machines;
+import gregtech.common.blocks.GT_Block_Ores_Abstract;
+import gregtech.common.blocks.GT_TileEntity_Ores;
+
+@ThreadSafeISBRH(perThread = true)
+public class GT_Renderer_Block implements ISimpleBlockRenderingHandler {
+
+ public static final float blockMin = 0.0F;
+ public static final float blockMax = 1.0F;
+ private static final float coverThickness = blockMax / 8.0F;
+ private static final float coverInnerMin = blockMin + coverThickness;
+ private static final float coverInnerMax = blockMax - coverThickness;
+
+ @Deprecated
+ public static GT_Renderer_Block INSTANCE;
+ public static int mRenderID;
+
+ public static void register() {
+ mRenderID = RenderingRegistry.getNextAvailableRenderId();
+ INSTANCE = new GT_Renderer_Block();
+ RenderingRegistry.registerBlockHandler(INSTANCE);
+ }
+
+ private final ITexture[][] textureArray = new ITexture[6][];
+
+ public boolean renderStandardBlock(IBlockAccess aWorld, int aX, int aY, int aZ, Block aBlock,
+ RenderBlocks aRenderer) {
+ final TileEntity tTileEntity = aWorld.getTileEntity(aX, aY, aZ);
+ if (tTileEntity instanceof IPipeRenderedTileEntity pipeRenderedTileEntity) {
+ textureArray[0] = pipeRenderedTileEntity.getTextureCovered(DOWN);
+ textureArray[1] = pipeRenderedTileEntity.getTextureCovered(UP);
+ textureArray[2] = pipeRenderedTileEntity.getTextureCovered(NORTH);
+ textureArray[3] = pipeRenderedTileEntity.getTextureCovered(SOUTH);
+ textureArray[4] = pipeRenderedTileEntity.getTextureCovered(WEST);
+ textureArray[5] = pipeRenderedTileEntity.getTextureCovered(EAST);
+ return renderStandardBlock(aWorld, aX, aY, aZ, aBlock, aRenderer, textureArray);
+ }
+ if (tTileEntity instanceof IAllSidedTexturedTileEntity allSidedTexturedTileEntity) {
+ ITexture[] texture = allSidedTexturedTileEntity.getTexture(aBlock);
+ textureArray[0] = texture;
+ textureArray[1] = texture;
+ textureArray[2] = texture;
+ textureArray[3] = texture;
+ textureArray[4] = texture;
+ textureArray[5] = texture;
+ return renderStandardBlock(aWorld, aX, aY, aZ, aBlock, aRenderer, textureArray);
+ }
+ if (tTileEntity instanceof ITexturedTileEntity texturedTileEntity) {
+ textureArray[0] = texturedTileEntity.getTexture(aBlock, DOWN);
+ textureArray[1] = texturedTileEntity.getTexture(aBlock, UP);
+ textureArray[2] = texturedTileEntity.getTexture(aBlock, NORTH);
+ textureArray[3] = texturedTileEntity.getTexture(aBlock, SOUTH);
+ textureArray[4] = texturedTileEntity.getTexture(aBlock, WEST);
+ textureArray[5] = texturedTileEntity.getTexture(aBlock, EAST);
+ return renderStandardBlock(aWorld, aX, aY, aZ, aBlock, aRenderer, textureArray);
+ }
+ return false;
+ }
+
+ public boolean renderStandardBlock(IBlockAccess aWorld, int aX, int aY, int aZ, Block aBlock,
+ RenderBlocks aRenderer, ITexture[][] aTextures) {
+ aBlock.setBlockBounds(blockMin, blockMin, blockMin, blockMax, blockMax, blockMax);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+
+ renderNegativeYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, aTextures[SIDE_DOWN], true);
+ renderPositiveYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, aTextures[SIDE_UP], true);
+ renderNegativeZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, aTextures[SIDE_NORTH], true);
+ renderPositiveZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, aTextures[SIDE_SOUTH], true);
+ renderNegativeXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, aTextures[SIDE_WEST], true);
+ renderPositiveXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, aTextures[SIDE_EAST], true);
+ return true;
+ }
+
+ final ITexture[][] tIcons = new ITexture[VALID_DIRECTIONS.length][];
+ final ITexture[][] tCovers = new ITexture[VALID_DIRECTIONS.length][];
+ final boolean[] tIsCovered = new boolean[VALID_DIRECTIONS.length];
+
+ public boolean renderPipeBlock(IBlockAccess aWorld, int aX, int aY, int aZ, Block aBlock,
+ IPipeRenderedTileEntity aTileEntity, RenderBlocks aRenderer) {
+ final byte aConnections = aTileEntity.getConnections();
+ if ((aConnections & (HAS_FRESHFOAM | HAS_HARDENEDFOAM)) != 0) {
+ return renderStandardBlock(aWorld, aX, aY, aZ, aBlock, aRenderer);
+ }
+ final float thickness = aTileEntity.getThickNess();
+ if (thickness >= 0.99F) {
+ return renderStandardBlock(aWorld, aX, aY, aZ, aBlock, aRenderer);
+ }
+ // Range of block occupied by pipe
+ final float pipeMin = (blockMax - thickness) / 2.0F;
+ final float pipeMax = blockMax - pipeMin;
+
+ for (int i = 0; i < VALID_DIRECTIONS.length; i++) {
+ final ForgeDirection iSide = VALID_DIRECTIONS[i];
+ tIsCovered[i] = (aTileEntity.getCoverIDAtSide(iSide) != 0);
+ tCovers[i] = aTileEntity.getTexture(aBlock, iSide);
+ tIcons[i] = aTileEntity.getTextureUncovered(iSide);
+
+ }
+
+ switch (aConnections) {
+ case NO_CONNECTION -> {
+ aBlock.setBlockBounds(pipeMin, pipeMin, pipeMin, pipeMax, pipeMax, pipeMax);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+ renderNegativeYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_DOWN], false);
+ renderPositiveYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_UP], false);
+ renderNegativeZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_NORTH], false);
+ renderPositiveZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_SOUTH], false);
+ renderNegativeXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_WEST], false);
+ renderPositiveXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_EAST], false);
+ }
+ case CONNECTED_EAST | CONNECTED_WEST -> {
+ // EAST - WEST Pipe Sides
+ aBlock.setBlockBounds(blockMin, pipeMin, pipeMin, blockMax, pipeMax, pipeMax);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+ renderNegativeYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_DOWN], false);
+ renderPositiveYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_UP], false);
+ renderNegativeZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_NORTH], false);
+ renderPositiveZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_SOUTH], false);
+
+ // EAST - WEST Pipe Ends
+ renderNegativeXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_WEST], false);
+ renderPositiveXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_EAST], false);
+ }
+ case CONNECTED_DOWN | CONNECTED_UP -> {
+ // UP - DOWN Pipe Sides
+ aBlock.setBlockBounds(pipeMin, blockMin, pipeMin, pipeMax, blockMax, pipeMax);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+ renderNegativeZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_NORTH], false);
+ renderPositiveZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_SOUTH], false);
+ renderNegativeXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_WEST], false);
+ renderPositiveXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_EAST], false);
+
+ // UP - DOWN Pipe Ends
+ renderNegativeYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_DOWN], false);
+ renderPositiveYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_UP], false);
+ }
+ case CONNECTED_NORTH | CONNECTED_SOUTH -> {
+ // NORTH - SOUTH Pipe Sides
+ aBlock.setBlockBounds(pipeMin, pipeMin, blockMin, pipeMax, pipeMax, blockMax);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+ renderNegativeYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_DOWN], false);
+ renderPositiveYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_UP], false);
+ renderNegativeXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_WEST], false);
+ renderPositiveXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_EAST], false);
+
+ // NORTH - SOUTH Pipe Ends
+ renderNegativeZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_NORTH], false);
+ renderPositiveZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_SOUTH], false);
+ }
+ default -> {
+ if ((aConnections & CONNECTED_WEST) == 0) {
+ aBlock.setBlockBounds(pipeMin, pipeMin, pipeMin, pipeMax, pipeMax, pipeMax);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+ } else {
+ aBlock.setBlockBounds(blockMin, pipeMin, pipeMin, pipeMin, pipeMax, pipeMax);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+ renderNegativeYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_DOWN], false);
+ renderPositiveYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_UP], false);
+ renderNegativeZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_NORTH], false);
+ renderPositiveZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_SOUTH], false);
+ }
+ renderNegativeXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_WEST], false);
+ if ((aConnections & CONNECTED_EAST) == 0) {
+ aBlock.setBlockBounds(pipeMin, pipeMin, pipeMin, pipeMax, pipeMax, pipeMax);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+ } else {
+ aBlock.setBlockBounds(pipeMax, pipeMin, pipeMin, blockMax, pipeMax, pipeMax);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+ renderNegativeYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_DOWN], false);
+ renderPositiveYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_UP], false);
+ renderNegativeZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_NORTH], false);
+ renderPositiveZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_SOUTH], false);
+ }
+ renderPositiveXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_EAST], false);
+ if ((aConnections & CONNECTED_DOWN) == 0) {
+ aBlock.setBlockBounds(pipeMin, pipeMin, pipeMin, pipeMax, pipeMax, pipeMax);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+ } else {
+ aBlock.setBlockBounds(pipeMin, blockMin, pipeMin, pipeMax, pipeMin, pipeMax);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+ renderNegativeZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_NORTH], false);
+ renderPositiveZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_SOUTH], false);
+ renderNegativeXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_WEST], false);
+ renderPositiveXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_EAST], false);
+ }
+ renderNegativeYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_DOWN], false);
+ if ((aConnections & CONNECTED_UP) == 0) {
+ aBlock.setBlockBounds(pipeMin, pipeMin, pipeMin, pipeMax, pipeMax, pipeMax);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+ } else {
+ aBlock.setBlockBounds(pipeMin, pipeMax, pipeMin, pipeMax, blockMax, pipeMax);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+ renderNegativeZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_NORTH], false);
+ renderPositiveZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_SOUTH], false);
+ renderNegativeXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_WEST], false);
+ renderPositiveXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_EAST], false);
+ }
+ renderPositiveYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_UP], false);
+ if ((aConnections & CONNECTED_NORTH) == 0) {
+ aBlock.setBlockBounds(pipeMin, pipeMin, pipeMin, pipeMax, pipeMax, pipeMax);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+ } else {
+ aBlock.setBlockBounds(pipeMin, pipeMin, blockMin, pipeMax, pipeMax, pipeMin);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+ renderNegativeYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_DOWN], false);
+ renderPositiveYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_UP], false);
+ renderNegativeXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_WEST], false);
+ renderPositiveXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_EAST], false);
+ }
+ renderNegativeZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_NORTH], false);
+ if ((aConnections & CONNECTED_SOUTH) == 0) {
+ aBlock.setBlockBounds(pipeMin, pipeMin, pipeMin, pipeMax, pipeMax, pipeMax);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+ } else {
+ aBlock.setBlockBounds(pipeMin, pipeMin, pipeMax, pipeMax, pipeMax, blockMax);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+ renderNegativeYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_DOWN], false);
+ renderPositiveYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_UP], false);
+ renderNegativeXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_WEST], false);
+ renderPositiveXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_EAST], false);
+ }
+ renderPositiveZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tIcons[SIDE_SOUTH], false);
+ }
+ }
+
+ // Render covers on pipes
+ if (tIsCovered[SIDE_DOWN]) {
+ aBlock.setBlockBounds(blockMin, blockMin, blockMin, blockMax, coverInnerMin, blockMax);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+ if (!tIsCovered[SIDE_NORTH]) {
+ renderNegativeZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_DOWN], false);
+ }
+ if (!tIsCovered[SIDE_SOUTH]) {
+ renderPositiveZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_DOWN], false);
+ }
+ if (!tIsCovered[SIDE_WEST]) {
+ renderNegativeXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_DOWN], false);
+ }
+ if (!tIsCovered[SIDE_EAST]) {
+ renderPositiveXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_DOWN], false);
+ }
+ renderPositiveYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_DOWN], false);
+ if ((aConnections & CONNECTED_DOWN) != 0) {
+ // Split outer face to leave hole for pipe
+ // Lower panel
+ aRenderer.setRenderBounds(blockMin, blockMin, blockMin, blockMax, blockMin, pipeMin);
+ renderNegativeYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_DOWN], false);
+ // Upper panel
+ aRenderer.setRenderBounds(blockMin, blockMin, pipeMax, blockMax, blockMin, blockMax);
+ renderNegativeYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_DOWN], false);
+ // Middle left panel
+ aRenderer.setRenderBounds(blockMin, blockMin, pipeMin, pipeMin, blockMin, pipeMax);
+ renderNegativeYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_DOWN], false);
+ // Middle right panel
+ aRenderer.setRenderBounds(pipeMax, blockMin, pipeMin, blockMax, blockMin, pipeMax);
+ }
+ renderNegativeYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_DOWN], false);
+ }
+
+ if (tIsCovered[SIDE_UP]) {
+ aBlock.setBlockBounds(blockMin, coverInnerMax, blockMin, blockMax, blockMax, blockMax);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+ if (!tIsCovered[SIDE_NORTH]) {
+ renderNegativeZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_UP], false);
+ }
+ if (!tIsCovered[SIDE_SOUTH]) {
+ renderPositiveZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_UP], false);
+ }
+ if (!tIsCovered[SIDE_WEST]) {
+ renderNegativeXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_UP], false);
+ }
+ if (!tIsCovered[SIDE_EAST]) {
+ renderPositiveXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_UP], false);
+ }
+ renderNegativeYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_UP], false);
+ if ((aConnections & CONNECTED_UP) != 0) {
+ // Split outer face to leave hole for pipe
+ // Lower panel
+ aRenderer.setRenderBounds(blockMin, blockMax, blockMin, blockMax, blockMax, pipeMin);
+ renderPositiveYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_UP], false);
+ // Upper panel
+ aRenderer.setRenderBounds(blockMin, blockMax, pipeMax, blockMax, blockMax, blockMax);
+ renderPositiveYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_UP], false);
+ // Middle left panel
+ aRenderer.setRenderBounds(blockMin, blockMax, pipeMin, pipeMin, blockMax, pipeMax);
+ renderPositiveYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_UP], false);
+ // Middle right panel
+ aRenderer.setRenderBounds(pipeMax, blockMax, pipeMin, blockMax, blockMax, pipeMax);
+ }
+ renderPositiveYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_UP], false);
+ }
+
+ if (tIsCovered[SIDE_NORTH]) {
+ aBlock.setBlockBounds(blockMin, blockMin, blockMin, blockMax, blockMax, coverInnerMin);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+ if (!tIsCovered[SIDE_DOWN]) {
+ renderNegativeYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_NORTH], false);
+ }
+ if (!tIsCovered[SIDE_UP]) {
+ renderPositiveYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_NORTH], false);
+ }
+ if (!tIsCovered[SIDE_WEST]) {
+ renderNegativeXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_NORTH], false);
+ }
+ if (!tIsCovered[SIDE_EAST]) {
+ renderPositiveXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_NORTH], false);
+ }
+ renderPositiveZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_NORTH], false);
+ if ((aConnections & CONNECTED_NORTH) != 0) {
+ // Split outer face to leave hole for pipe
+ // Lower panel
+ aRenderer.setRenderBounds(blockMin, blockMin, blockMin, blockMax, pipeMin, blockMin);
+ renderNegativeZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_NORTH], false);
+ // Upper panel
+ aRenderer.setRenderBounds(blockMin, pipeMax, blockMin, blockMax, blockMax, blockMin);
+ renderNegativeZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_NORTH], false);
+ // Middle left panel
+ aRenderer.setRenderBounds(blockMin, pipeMin, blockMin, pipeMin, pipeMax, blockMin);
+ renderNegativeZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_NORTH], false);
+ // Middle right panel
+ aRenderer.setRenderBounds(pipeMax, pipeMin, blockMin, blockMax, pipeMax, blockMin);
+ }
+ renderNegativeZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_NORTH], false);
+ }
+
+ if (tIsCovered[SIDE_SOUTH]) {
+ aBlock.setBlockBounds(blockMin, blockMin, coverInnerMax, blockMax, blockMax, blockMax);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+ if (!tIsCovered[SIDE_DOWN]) {
+ renderNegativeYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_SOUTH], false);
+ }
+ if (!tIsCovered[SIDE_UP]) {
+ renderPositiveYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_SOUTH], false);
+ }
+ if (!tIsCovered[SIDE_WEST]) {
+ renderNegativeXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_SOUTH], false);
+ }
+ if (!tIsCovered[SIDE_EAST]) {
+ renderPositiveXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_SOUTH], false);
+ }
+ renderNegativeZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_SOUTH], false);
+ if ((aConnections & CONNECTED_SOUTH) != 0) {
+ // Split outer face to leave hole for pipe
+ // Lower panel
+ aRenderer.setRenderBounds(blockMin, blockMin, blockMax, blockMax, pipeMin, blockMax);
+ renderPositiveZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_SOUTH], false);
+ // Upper panel
+ aRenderer.setRenderBounds(blockMin, pipeMax, blockMax, blockMax, blockMax, blockMax);
+ renderPositiveZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_SOUTH], false);
+ // Middle left panel
+ aRenderer.setRenderBounds(blockMin, pipeMin, blockMax, pipeMin, pipeMax, blockMax);
+ renderPositiveZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_SOUTH], false);
+ // Middle right panel
+ aRenderer.setRenderBounds(pipeMax, pipeMin, blockMax, blockMax, pipeMax, blockMax);
+ }
+ renderPositiveZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_SOUTH], false);
+ }
+
+ if (tIsCovered[SIDE_WEST]) {
+ aBlock.setBlockBounds(blockMin, blockMin, blockMin, coverInnerMin, blockMax, blockMax);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+ if (!tIsCovered[SIDE_DOWN]) {
+ renderNegativeYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_WEST], false);
+ }
+ if (!tIsCovered[SIDE_UP]) {
+ renderPositiveYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_WEST], false);
+ }
+ if (!tIsCovered[SIDE_NORTH]) {
+ renderNegativeZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_WEST], false);
+ }
+ if (!tIsCovered[SIDE_SOUTH]) {
+ renderPositiveZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_WEST], false);
+ }
+ renderPositiveXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_WEST], false);
+ if ((aConnections & CONNECTED_WEST) != 0) {
+ // Split outer face to leave hole for pipe
+ // Lower panel
+ aRenderer.setRenderBounds(blockMin, blockMin, blockMin, blockMin, pipeMin, blockMax);
+ renderNegativeXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_WEST], false);
+ // Upper panel
+ aRenderer.setRenderBounds(blockMin, pipeMax, blockMin, blockMin, blockMax, blockMax);
+ renderNegativeXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_WEST], false);
+ // Middle left panel
+ aRenderer.setRenderBounds(blockMin, pipeMin, blockMin, blockMin, pipeMax, pipeMin);
+ renderNegativeXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_WEST], false);
+ // Middle right panel
+ aRenderer.setRenderBounds(blockMin, pipeMin, pipeMax, blockMin, pipeMax, blockMax);
+ }
+ renderNegativeXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_WEST], false);
+ }
+
+ if (tIsCovered[SIDE_EAST]) {
+ aBlock.setBlockBounds(coverInnerMax, blockMin, blockMin, blockMax, blockMax, blockMax);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+ if (!tIsCovered[SIDE_DOWN]) {
+ renderNegativeYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_EAST], false);
+ }
+ if (!tIsCovered[SIDE_UP]) {
+ renderPositiveYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_EAST], false);
+ }
+ if (!tIsCovered[SIDE_NORTH]) {
+ renderNegativeZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_EAST], false);
+ }
+ if (!tIsCovered[SIDE_SOUTH]) {
+ renderPositiveZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_EAST], false);
+ }
+ renderNegativeXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_EAST], false);
+
+ if ((aConnections & CONNECTED_EAST) != 0) {
+ // Split outer face to leave hole for pipe
+ // Lower panel
+ aRenderer.setRenderBounds(blockMax, blockMin, blockMin, blockMax, pipeMin, blockMax);
+ renderPositiveXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_EAST], false);
+ // Upper panel
+ aRenderer.setRenderBounds(blockMax, pipeMax, blockMin, blockMax, blockMax, blockMax);
+ renderPositiveXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_EAST], false);
+ // Middle left panel
+ aRenderer.setRenderBounds(blockMax, pipeMin, blockMin, blockMax, pipeMax, pipeMin);
+ renderPositiveXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_EAST], false);
+ // Middle right panel
+ aRenderer.setRenderBounds(blockMax, pipeMin, pipeMax, blockMax, pipeMax, blockMax);
+ }
+ renderPositiveXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, tCovers[SIDE_EAST], false);
+ }
+ aBlock.setBlockBounds(blockMin, blockMin, blockMin, blockMax, blockMax, blockMax);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+
+ return true;
+ }
+
+ @SideOnly(Side.CLIENT)
+ public static void addHitEffects(EffectRenderer effectRenderer, Block block, World world, int x, int y, int z,
+ int ordinalSide) {
+ double rX = x + XSTR.XSTR_INSTANCE.nextDouble() * 0.8 + 0.1;
+ double rY = y + XSTR.XSTR_INSTANCE.nextDouble() * 0.8 + 0.1;
+ double rZ = z + XSTR.XSTR_INSTANCE.nextDouble() * 0.8 + 0.1;
+ if (ordinalSide == 0) {
+ rY = y - 0.1;
+ } else if (ordinalSide == 1) {
+ rY = y + 1.1;
+ } else if (ordinalSide == 2) {
+ rZ = z - 0.1;
+ } else if (ordinalSide == 3) {
+ rZ = z + 1.1;
+ } else if (ordinalSide == 4) {
+ rX = x - 0.1;
+ } else if (ordinalSide == 5) {
+ rX = x + 1.1;
+ }
+ effectRenderer.addEffect(
+ (new EntityDiggingFX(
+ world,
+ rX,
+ rY,
+ rZ,
+ 0.0,
+ 0.0,
+ 0.0,
+ block,
+ block.getDamageValue(world, x, y, z),
+ ordinalSide)).applyColourMultiplier(x, y, z)
+ .multiplyVelocity(0.2F)
+ .multipleParticleScaleBy(0.6F));
+ }
+
+ @SideOnly(Side.CLIENT)
+ public static void addDestroyEffects(EffectRenderer effectRenderer, Block block, World world, int x, int y, int z) {
+ for (int iX = 0; iX < 4; ++iX) {
+ for (int iY = 0; iY < 4; ++iY) {
+ for (int iZ = 0; iZ < 4; ++iZ) {
+ final double bX = x + (iX + 0.5) / 4.0;
+ final double bY = y + (iY + 0.5) / 4.0;
+ final double bZ = z + (iZ + 0.5) / 4.0;
+ effectRenderer.addEffect(
+ (new EntityDiggingFX(
+ world,
+ bX,
+ bY,
+ bZ,
+ bX - x - 0.5,
+ bY - y - 0.5,
+ bZ - z - 0.5,
+ block,
+ block.getDamageValue(world, x, y, z))).applyColourMultiplier(x, y, z));
+ }
+ }
+ }
+ }
+
+ final GT_TileEntity_Ores tTileEntity = new GT_TileEntity_Ores();
+
+ @Override
+ public void renderInventoryBlock(Block aBlock, int aMeta, int aModelID, RenderBlocks aRenderer) {
+ aRenderer.enableAO = false;
+ aRenderer.useInventoryTint = true;
+
+ GL11.glRotatef(90.0F, 0.0F, 1.0F, 0.0F);
+ GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
+ if (aBlock instanceof GT_Block_Ores_Abstract) {
+ tTileEntity.mMetaData = ((short) aMeta);
+
+ aBlock.setBlockBoundsForItemRender();
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+ // spotless:off
+ ITexture[] texture = tTileEntity.getTexture(aBlock);
+ renderNegativeYFacing(null, aRenderer, aBlock, 0, 0, 0, texture, true);
+ renderPositiveYFacing(null, aRenderer, aBlock, 0, 0, 0, texture, true);
+ renderNegativeZFacing(null, aRenderer, aBlock, 0, 0, 0, texture, true);
+ renderPositiveZFacing(null, aRenderer, aBlock, 0, 0, 0, texture, true);
+ renderNegativeXFacing(null, aRenderer, aBlock, 0, 0, 0, texture, true);
+ renderPositiveXFacing(null, aRenderer, aBlock, 0, 0, 0, texture, true);
+ // spotless:on
+ } else if (aMeta > 0 && (aMeta < GregTech_API.METATILEENTITIES.length)
+ && aBlock instanceof GT_Block_Machines
+ && (GregTech_API.METATILEENTITIES[aMeta] != null)
+ && (!GregTech_API.METATILEENTITIES[aMeta].renderInInventory(aBlock, aMeta, aRenderer))) {
+ renderNormalInventoryMetaTileEntity(aBlock, aMeta, aRenderer);
+ }
+ aBlock.setBlockBounds(blockMin, blockMin, blockMin, blockMax, blockMax, blockMax);
+
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+
+ GL11.glTranslatef(0.5F, 0.5F, 0.5F);
+ aRenderer.useInventoryTint = false;
+ }
+
+ private static void renderNormalInventoryMetaTileEntity(Block aBlock, int aMeta, RenderBlocks aRenderer) {
+ if ((aMeta <= 0) || (aMeta >= GregTech_API.METATILEENTITIES.length)) {
+ return;
+ }
+ final IMetaTileEntity tMetaTileEntity = GregTech_API.METATILEENTITIES[aMeta];
+ if (tMetaTileEntity == null) {
+ return;
+ }
+ aBlock.setBlockBoundsForItemRender();
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+
+ final IGregTechTileEntity iGregTechTileEntity = tMetaTileEntity.getBaseMetaTileEntity();
+
+ // spotless:off
+ if ((iGregTechTileEntity instanceof IPipeRenderedTileEntity renderedPipe)
+ && (tMetaTileEntity instanceof MetaPipeEntity pipeEntity)) {
+ final float tThickness = renderedPipe.getThickNess();
+ final float pipeMin = (blockMax - tThickness) / 2.0F;
+ final float pipeMax = blockMax - pipeMin;
+
+ aBlock.setBlockBounds(blockMin, pipeMin, pipeMin, blockMax, pipeMax, pipeMax);
+ aRenderer.setRenderBoundsFromBlock(aBlock);
+ renderNegativeYFacing(null, aRenderer, aBlock, 0, 0, 0, pipeEntity.getTexture(iGregTechTileEntity, DOWN, (CONNECTED_WEST | CONNECTED_EAST), -1, false, false), true);
+ renderPositiveYFacing(null, aRenderer, aBlock, 0, 0, 0, pipeEntity.getTexture(iGregTechTileEntity, UP, (CONNECTED_WEST | CONNECTED_EAST), -1, false, false), true);
+ renderNegativeZFacing(null, aRenderer, aBlock, 0, 0, 0, pipeEntity.getTexture(iGregTechTileEntity, NORTH, (CONNECTED_WEST | CONNECTED_EAST), -1, false, false), true);
+ renderPositiveZFacing(null, aRenderer, aBlock, 0, 0, 0, pipeEntity.getTexture(iGregTechTileEntity, SOUTH, (CONNECTED_WEST | CONNECTED_EAST), -1, false, false), true);
+ renderNegativeXFacing(null, aRenderer, aBlock, 0, 0, 0, pipeEntity.getTexture(iGregTechTileEntity, WEST, (CONNECTED_WEST | CONNECTED_EAST), -1, true, false), true);
+ renderPositiveXFacing(null, aRenderer, aBlock, 0, 0, 0, pipeEntity.getTexture(iGregTechTileEntity, EAST, (CONNECTED_WEST | CONNECTED_EAST), -1, true, false), true);
+ } else {
+ renderNegativeYFacing(null, aRenderer, aBlock, 0, 0, 0, tMetaTileEntity.getTexture(iGregTechTileEntity, DOWN, WEST, -1, true, false), true);
+ renderPositiveYFacing(null, aRenderer, aBlock, 0, 0, 0, tMetaTileEntity.getTexture(iGregTechTileEntity, UP, WEST, -1, true, false), true);
+ renderNegativeZFacing(null, aRenderer, aBlock, 0, 0, 0, tMetaTileEntity.getTexture(iGregTechTileEntity, NORTH, WEST, -1, true, false), true);
+ renderPositiveZFacing(null, aRenderer, aBlock, 0, 0, 0, tMetaTileEntity.getTexture(iGregTechTileEntity, SOUTH, WEST, -1, true, false), true);
+ renderNegativeXFacing(null, aRenderer, aBlock, 0, 0, 0, tMetaTileEntity.getTexture(iGregTechTileEntity, WEST, WEST, -1, true, false), true);
+ renderPositiveXFacing(null, aRenderer, aBlock, 0, 0, 0, tMetaTileEntity.getTexture(iGregTechTileEntity, EAST, WEST, -1, true, false), true);
+ }
+ // spotless:on
+ }
+
+ public static void renderNegativeYFacing(IBlockAccess aWorld, RenderBlocks aRenderer, Block aBlock, int aX, int aY,
+ int aZ, ITexture[] aIcon, boolean aFullBlock) {
+ if (aWorld != null) {
+ if ((aFullBlock) && (!aBlock.shouldSideBeRendered(aWorld, aX, aY - 1, aZ, 0))) return;
+ Tessellator.instance
+ .setBrightness(aBlock.getMixedBrightnessForBlock(aWorld, aX, aFullBlock ? aY - 1 : aY, aZ));
+ }
+ if (aIcon == null) return;
+ for (final ITexture iTexture : aIcon) {
+ if (iTexture != null) {
+ iTexture.renderYNeg(aRenderer, aBlock, aX, aY, aZ);
+ }
+ }
+ }
+
+ public static void renderPositiveYFacing(IBlockAccess aWorld, RenderBlocks aRenderer, Block aBlock, int aX, int aY,
+ int aZ, ITexture[] aIcon, boolean aFullBlock) {
+ if (aWorld != null) {
+ if ((aFullBlock) && (!aBlock.shouldSideBeRendered(aWorld, aX, aY + 1, aZ, 1))) return;
+ Tessellator.instance
+ .setBrightness(aBlock.getMixedBrightnessForBlock(aWorld, aX, aFullBlock ? aY + 1 : aY, aZ));
+ }
+ if (aIcon == null) return;
+ for (final ITexture iTexture : aIcon) {
+ if (iTexture != null) {
+ iTexture.renderYPos(aRenderer, aBlock, aX, aY, aZ);
+ }
+ }
+ }
+
+ public static void renderNegativeZFacing(IBlockAccess aWorld, RenderBlocks aRenderer, Block aBlock, int aX, int aY,
+ int aZ, ITexture[] aIcon, boolean aFullBlock) {
+ if (aWorld != null) {
+ if ((aFullBlock) && (!aBlock.shouldSideBeRendered(aWorld, aX, aY, aZ - 1, 2))) return;
+ Tessellator.instance
+ .setBrightness(aBlock.getMixedBrightnessForBlock(aWorld, aX, aY, aFullBlock ? aZ - 1 : aZ));
+ }
+ if (aIcon == null) return;
+ for (final ITexture iTexture : aIcon) {
+ if (iTexture != null) {
+ iTexture.renderZNeg(aRenderer, aBlock, aX, aY, aZ);
+ }
+ }
+ }
+
+ public static void renderPositiveZFacing(IBlockAccess aWorld, RenderBlocks aRenderer, Block aBlock, int aX, int aY,
+ int aZ, ITexture[] aIcon, boolean aFullBlock) {
+ if (aWorld != null) {
+ if ((aFullBlock) && (!aBlock.shouldSideBeRendered(aWorld, aX, aY, aZ + 1, 3))) return;
+ Tessellator.instance
+ .setBrightness(aBlock.getMixedBrightnessForBlock(aWorld, aX, aY, aFullBlock ? aZ + 1 : aZ));
+ }
+ if (aIcon == null) return;
+ for (final ITexture iTexture : aIcon) {
+ if (iTexture != null) {
+ iTexture.renderZPos(aRenderer, aBlock, aX, aY, aZ);
+ }
+ }
+ }
+
+ public static void renderNegativeXFacing(IBlockAccess aWorld, RenderBlocks aRenderer, Block aBlock, int aX, int aY,
+ int aZ, ITexture[] aIcon, boolean aFullBlock) {
+ if (aWorld != null) {
+ if ((aFullBlock) && (!aBlock.shouldSideBeRendered(aWorld, aX - 1, aY, aZ, 4))) return;
+ Tessellator.instance
+ .setBrightness(aBlock.getMixedBrightnessForBlock(aWorld, aFullBlock ? aX - 1 : aX, aY, aZ));
+ }
+ if (aIcon == null) return;
+ for (final ITexture iTexture : aIcon) {
+ if (iTexture != null) {
+ iTexture.renderXNeg(aRenderer, aBlock, aX, aY, aZ);
+ }
+ }
+ }
+
+ public static void renderPositiveXFacing(IBlockAccess aWorld, RenderBlocks aRenderer, Block aBlock, int aX, int aY,
+ int aZ, ITexture[] aIcon, boolean aFullBlock) {
+ if (aWorld != null) {
+ if ((aFullBlock) && (!aBlock.shouldSideBeRendered(aWorld, aX + 1, aY, aZ, 5))) return;
+ Tessellator.instance
+ .setBrightness(aBlock.getMixedBrightnessForBlock(aWorld, aFullBlock ? aX + 1 : aX, aY, aZ));
+ }
+ if (aIcon == null) return;
+ for (final ITexture iTexture : aIcon) {
+ if (iTexture != null) {
+ iTexture.renderXPos(aRenderer, aBlock, aX, aY, aZ);
+ }
+ }
+ }
+
+ @Override
+ public boolean renderWorldBlock(IBlockAccess aWorld, int aX, int aY, int aZ, Block aBlock, int aModelID,
+ RenderBlocks aRenderer) {
+ aRenderer.enableAO = Minecraft.isAmbientOcclusionEnabled() && GT_Mod.gregtechproxy.mRenderTileAmbientOcclusion;
+ aRenderer.useInventoryTint = false;
+
+ final TileEntity tileEntity = aWorld.getTileEntity(aX, aY, aZ);
+ if (tileEntity == null) return false;
+ if (tileEntity instanceof IGregTechTileEntity) {
+ final IMetaTileEntity metaTileEntity;
+ if ((metaTileEntity = ((IGregTechTileEntity) tileEntity).getMetaTileEntity()) != null
+ && metaTileEntity.renderInWorld(aWorld, aX, aY, aZ, aBlock, aRenderer)) {
+ aRenderer.enableAO = false;
+ return true;
+ }
+ }
+ if (tileEntity instanceof IPipeRenderedTileEntity
+ && renderPipeBlock(aWorld, aX, aY, aZ, aBlock, (IPipeRenderedTileEntity) tileEntity, aRenderer)) {
+ aRenderer.enableAO = false;
+ return true;
+ }
+ if (renderStandardBlock(aWorld, aX, aY, aZ, aBlock, aRenderer)) {
+ aRenderer.enableAO = false;
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean shouldRender3DInInventory(int aModel) {
+ return true;
+ }
+
+ @Override
+ public int getRenderId() {
+ return this.mRenderID;
+ }
+}
diff --git a/src/main/java/gregtech/common/render/GT_Renderer_Entity_Arrow.java b/src/main/java/gregtech/common/render/GT_Renderer_Entity_Arrow.java
new file mode 100644
index 0000000000..e72a79514e
--- /dev/null
+++ b/src/main/java/gregtech/common/render/GT_Renderer_Entity_Arrow.java
@@ -0,0 +1,23 @@
+package gregtech.common.render;
+
+import net.minecraft.client.renderer.entity.RenderArrow;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.projectile.EntityArrow;
+import net.minecraft.util.ResourceLocation;
+
+import cpw.mods.fml.client.registry.RenderingRegistry;
+
+public class GT_Renderer_Entity_Arrow extends RenderArrow {
+
+ private final ResourceLocation mTexture;
+
+ public GT_Renderer_Entity_Arrow(Class<? extends EntityArrow> aArrowClass, String aTextureName) {
+ this.mTexture = new ResourceLocation("gregtech:textures/entity/" + aTextureName + ".png");
+ RenderingRegistry.registerEntityRenderingHandler(aArrowClass, this);
+ }
+
+ @Override
+ protected ResourceLocation getEntityTexture(Entity p_110775_1_) {
+ return this.mTexture;
+ }
+}
diff --git a/src/main/java/gregtech/common/render/GT_SidedTexture.java b/src/main/java/gregtech/common/render/GT_SidedTexture.java
new file mode 100644
index 0000000000..7a851fd1e7
--- /dev/null
+++ b/src/main/java/gregtech/common/render/GT_SidedTexture.java
@@ -0,0 +1,78 @@
+package gregtech.common.render;
+
+import net.minecraft.block.Block;
+import net.minecraft.client.renderer.RenderBlocks;
+
+import gregtech.api.interfaces.IColorModulationContainer;
+import gregtech.api.interfaces.IIconContainer;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.render.TextureFactory;
+
+public class GT_SidedTexture extends GT_TextureBase implements ITexture, IColorModulationContainer {
+
+ protected final ITexture[] mTextures;
+ /**
+ * DO NOT MANIPULATE THE VALUES INSIDE THIS ARRAY!!!
+ * <p/>
+ * Just set this variable to another different Array instead. Otherwise some colored things will get Problems.
+ */
+ private final short[] mRGBa;
+
+ protected GT_SidedTexture(IIconContainer aIcon0, IIconContainer aIcon1, IIconContainer aIcon2,
+ IIconContainer aIcon3, IIconContainer aIcon4, IIconContainer aIcon5, short[] aRGBa, boolean aAllowAlpha) {
+ if (aRGBa.length != 4) throw new IllegalArgumentException("RGBa doesn't have 4 Values @ GT_RenderedTexture");
+ mTextures = new ITexture[] { TextureFactory.of(aIcon0, aRGBa, aAllowAlpha),
+ TextureFactory.of(aIcon1, aRGBa, aAllowAlpha), TextureFactory.of(aIcon2, aRGBa, aAllowAlpha),
+ TextureFactory.of(aIcon3, aRGBa, aAllowAlpha), TextureFactory.of(aIcon4, aRGBa, aAllowAlpha),
+ TextureFactory.of(aIcon5, aRGBa, aAllowAlpha) };
+ mRGBa = aRGBa;
+ }
+
+ @Override
+ public boolean isOldTexture() {
+ return false;
+ }
+
+ @Override
+ public void renderXPos(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ mTextures[5].renderXPos(aRenderer, aBlock, aX, aY, aZ);
+ }
+
+ @Override
+ public void renderXNeg(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ mTextures[4].renderXNeg(aRenderer, aBlock, aX, aY, aZ);
+ }
+
+ @Override
+ public void renderYPos(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ mTextures[1].renderYPos(aRenderer, aBlock, aX, aY, aZ);
+ }
+
+ @Override
+ public void renderYNeg(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ mTextures[0].renderYNeg(aRenderer, aBlock, aX, aY, aZ);
+ }
+
+ @Override
+ public void renderZPos(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ mTextures[3].renderZPos(aRenderer, aBlock, aX, aY, aZ);
+ }
+
+ @Override
+ public void renderZNeg(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ mTextures[2].renderZNeg(aRenderer, aBlock, aX, aY, aZ);
+ }
+
+ @Override
+ public short[] getRGBA() {
+ return mRGBa;
+ }
+
+ @Override
+ public boolean isValidTexture() {
+ for (ITexture renderedTexture : mTextures) {
+ if (!renderedTexture.isValidTexture()) return false;
+ }
+ return true;
+ }
+}
diff --git a/src/main/java/gregtech/common/render/GT_TextureBase.java b/src/main/java/gregtech/common/render/GT_TextureBase.java
new file mode 100644
index 0000000000..20188e2e01
--- /dev/null
+++ b/src/main/java/gregtech/common/render/GT_TextureBase.java
@@ -0,0 +1,31 @@
+package gregtech.common.render;
+
+import net.minecraft.client.renderer.RenderBlocks;
+import net.minecraft.client.renderer.Tessellator;
+
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.util.GT_UtilityClient;
+
+public abstract class GT_TextureBase implements ITexture {
+
+ protected boolean isDrawing = false;
+
+ @Override
+ public void startDrawingQuads(RenderBlocks aRenderer, float aNormalX, float aNormalY, float aNormalZ) {
+ if (aRenderer.useInventoryTint && (!isOldTexture() || !GT_UtilityClient.isDrawing(Tessellator.instance))) {
+ // Draw if we're not an old texture OR we are an old texture AND we're not already drawing
+ isDrawing = true;
+ Tessellator.instance.startDrawingQuads();
+ Tessellator.instance.setNormal(aNormalX, aNormalY, aNormalZ);
+ }
+ }
+
+ @Override
+ public void draw(RenderBlocks aRenderer) {
+ if (aRenderer.useInventoryTint && (!isOldTexture() || isDrawing)) {
+ // Draw if we're not an old texture OR we initiated the drawing
+ isDrawing = false;
+ Tessellator.instance.draw();
+ }
+ }
+}
diff --git a/src/main/java/gregtech/common/render/GT_TextureBuilder.java b/src/main/java/gregtech/common/render/GT_TextureBuilder.java
new file mode 100644
index 0000000000..af8a590fc1
--- /dev/null
+++ b/src/main/java/gregtech/common/render/GT_TextureBuilder.java
@@ -0,0 +1,151 @@
+package gregtech.common.render;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import net.minecraft.block.Block;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import gregtech.GT_Mod;
+import gregtech.api.enums.Dyes;
+import gregtech.api.enums.GT_Values;
+import gregtech.api.interfaces.IIconContainer;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.ITextureBuilder;
+
+@SuppressWarnings({ "unused", "ClassWithTooManyFields" })
+public class GT_TextureBuilder implements ITextureBuilder {
+
+ private final List<IIconContainer> iconContainerList;
+ private final List<ITexture> textureLayers;
+ private Block fromBlock;
+ private int fromMeta;
+ private ForgeDirection fromSide;
+ private short[] rgba;
+ private boolean allowAlpha;
+ private boolean stdOrient;
+ private boolean extFacing;
+ private boolean glow;
+ private Boolean worldCoord = null;
+
+ public GT_TextureBuilder() {
+ textureLayers = new ArrayList<>();
+ iconContainerList = new ArrayList<>();
+ rgba = Dyes._NULL.mRGBa;
+ allowAlpha = true;
+ stdOrient = false;
+ glow = false;
+ }
+
+ @Override
+ public ITextureBuilder setFromBlock(final Block block, final int meta) {
+ this.fromBlock = block;
+ this.fromMeta = meta;
+ this.fromSide = ForgeDirection.UNKNOWN;
+ return this;
+ }
+
+ @Override
+ public ITextureBuilder setFromSide(final ForgeDirection side) {
+ this.fromSide = side;
+ return this;
+ }
+
+ @Override
+ public ITextureBuilder addIcon(final IIconContainer... iconContainers) {
+ this.iconContainerList.addAll(Arrays.asList(iconContainers));
+ return this;
+ }
+
+ @Override
+ public ITextureBuilder setRGBA(final short[] rgba) {
+ this.rgba = rgba;
+ return this;
+ }
+
+ @Override
+ public ITextureBuilder addLayer(final ITexture... iTextures) {
+ this.textureLayers.addAll(Arrays.asList(iTextures));
+ return this;
+ }
+
+ @Override
+ public ITextureBuilder setAllowAlpha(final boolean allowAlpha) {
+ this.allowAlpha = allowAlpha;
+ return this;
+ }
+
+ @Override
+ public ITextureBuilder stdOrient() {
+ this.stdOrient = true;
+ return this;
+ }
+
+ @Override
+ public ITextureBuilder useWorldCoord() {
+ this.worldCoord = true;
+ return this;
+ }
+
+ @Override
+ public ITextureBuilder noWorldCoord() {
+ this.worldCoord = false;
+ return this;
+ }
+
+ @Override
+ public ITextureBuilder extFacing() {
+ this.extFacing = true;
+ return this;
+ }
+
+ @Override
+ public ITextureBuilder glow() {
+ glow = true;
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ @Override
+ public ITexture build() {
+ if (fromBlock != null) {
+ if (worldCoord == Boolean.TRUE || worldCoord == null && isCTMBlock(fromBlock, fromMeta))
+ return new GT_CopiedCTMBlockTexture(fromBlock, fromSide.ordinal(), fromMeta, rgba, allowAlpha);
+ else return new GT_CopiedBlockTexture(fromBlock, fromSide.ordinal(), fromMeta, rgba, allowAlpha);
+ }
+ if (worldCoord != null) throw new IllegalStateException("worldCoord without from block");
+ if (!textureLayers.isEmpty()) return new GT_MultiTexture(textureLayers.toArray(new ITexture[0]));
+ return switch (iconContainerList.size()) {
+ case 1 -> new GT_RenderedTexture(iconContainerList.get(0), rgba, allowAlpha, glow, stdOrient, extFacing);
+ case 6 -> new GT_SidedTexture(
+ iconContainerList.get(ForgeDirection.DOWN.ordinal()),
+ iconContainerList.get(ForgeDirection.UP.ordinal()),
+ iconContainerList.get(ForgeDirection.NORTH.ordinal()),
+ iconContainerList.get(ForgeDirection.SOUTH.ordinal()),
+ iconContainerList.get(ForgeDirection.WEST.ordinal()),
+ iconContainerList.get(ForgeDirection.EAST.ordinal()),
+ rgba,
+ allowAlpha);
+ default -> throw new IllegalStateException("Invalid sideIconContainer count");
+ };
+ }
+
+ private boolean isCTMBlock(Block fromBlock, int fromMeta) {
+ return GT_Mod.gregtechproxy.mCTMBlockCache
+ .computeIfAbsent(fromBlock, (byte) fromMeta, GT_TextureBuilder::apply);
+ }
+
+ private static Boolean apply(Block b, Byte m) {
+ Class<?> clazz = b.getClass();
+ while (clazz != Block.class) {
+ final String className = clazz.getName();
+ if (GT_Values.mCTMDisabledBlock.contains(className)) return false;
+ if (GT_Values.mCTMEnabledBlock.contains(className)) return true;
+ clazz = clazz.getSuperclass();
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/gregtech/common/render/IRenderedBlock.java b/src/main/java/gregtech/common/render/IRenderedBlock.java
new file mode 100644
index 0000000000..16268de750
--- /dev/null
+++ b/src/main/java/gregtech/common/render/IRenderedBlock.java
@@ -0,0 +1,114 @@
+package gregtech.common.render;
+
+import net.minecraft.block.Block;
+import net.minecraft.client.renderer.RenderBlocks;
+import net.minecraft.item.ItemStack;
+import net.minecraft.world.IBlockAccess;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import gregtech.api.enums.Textures;
+import gregtech.api.interfaces.ITexture;
+
+public interface IRenderedBlock {
+
+ /** @return the Textures to be rendered */
+ @SideOnly(Side.CLIENT)
+ ITexture[] getTexture(Block aBlock, ForgeDirection side, int aRenderPass, boolean[] aShouldSideBeRendered);
+
+ @SideOnly(Side.CLIENT)
+ ITexture[] getTexture(Block aBlock, ForgeDirection side, boolean isActive, int aRenderPass);
+
+ /** gets the Amount of Render Passes for this TileEntity or similar Handler. Only gets called once per Rendering. */
+ @SideOnly(Side.CLIENT)
+ int getRenderPasses(Block aBlock);
+
+ /** if this uses said Render Pass or if it can be skipped entirely. */
+ @SideOnly(Side.CLIENT)
+ boolean usesRenderPass(int aRenderPass);
+
+ /** sets the Block Size rendered; return false for letting it select the normal Block Bounds. */
+ @SideOnly(Side.CLIENT)
+ boolean setBlockBounds(Block aBlock, int aRenderPass);
+
+ /** returning true stops all the other Rendering from happening. */
+ @SideOnly(Side.CLIENT)
+ default boolean renderItem(Block aBlock, RenderBlocks aRenderer) {
+ return false;
+ }
+
+ /** returning true stops all the other Rendering from happening. */
+ @SideOnly(Side.CLIENT)
+ default boolean renderBlock(Block aBlock, RenderBlocks aRenderer, IBlockAccess aWorld, int aX, int aY, int aZ) {
+ return false;
+ }
+
+ /** if this Block lets the TileEntity or a similar Handler do all the Inventory Render work. */
+ @SideOnly(Side.CLIENT)
+ IRenderedBlock passRenderingToObject(ItemStack aStack);
+
+ /** if this Block lets the TileEntity or a similar Handler do all the World Render work. */
+ @SideOnly(Side.CLIENT)
+ IRenderedBlock passRenderingToObject(IBlockAccess aWorld, int aX, int aY, int aZ);
+
+ class ErrorRenderer implements IRenderedBlockSideCheck, IRenderedBlock {
+
+ public static final ErrorRenderer INSTANCE = new ErrorRenderer();
+ public ITexture[] mErrorTexture = Textures.BlockIcons.ERROR_RENDERING;
+
+ @Override
+ public ITexture[] getTexture(Block aBlock, ForgeDirection side, int aRenderPass,
+ boolean[] aShouldSideBeRendered) {
+ return mErrorTexture;
+ }
+
+ @Override
+ public ITexture[] getTexture(Block aBlock, ForgeDirection side, boolean isActive, int aRenderPass) {
+ return mErrorTexture;
+ }
+
+ @Override
+ public int getRenderPasses(Block aBlock) {
+ return 1;
+ }
+
+ @Override
+ public boolean usesRenderPass(int aRenderPass) {
+ return true;
+ }
+
+ @Override
+ public boolean setBlockBounds(Block aBlock, int aRenderPass) {
+ aBlock.setBlockBounds(-0.25F, -0.25F, -0.25F, 1.25F, 1.25F, 1.25F);
+ return true;
+ }
+
+ @Override
+ public boolean renderFullBlockSide(Block aBlock, RenderBlocks aRenderer, ForgeDirection side) {
+ return true;
+ }
+
+ @Override
+ public IRenderedBlock passRenderingToObject(ItemStack aStack) {
+ return this;
+ }
+
+ @Override
+ public IRenderedBlock passRenderingToObject(IBlockAccess aWorld, int aX, int aY, int aZ) {
+ return this;
+ }
+
+ @Override
+ public boolean renderBlock(Block aBlock, RenderBlocks aRenderer, IBlockAccess aWorld, int aX, int aY, int aZ) {
+ aBlock.setBlockBounds(-0.25F, -0.25F, -0.25F, 1.25F, 1.25F, 1.25F);
+ GT_Renderer_Block.renderNegativeYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, mErrorTexture, false);
+ GT_Renderer_Block.renderPositiveYFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, mErrorTexture, false);
+ GT_Renderer_Block.renderNegativeZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, mErrorTexture, false);
+ GT_Renderer_Block.renderPositiveZFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, mErrorTexture, false);
+ GT_Renderer_Block.renderNegativeXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, mErrorTexture, false);
+ GT_Renderer_Block.renderPositiveXFacing(aWorld, aRenderer, aBlock, aX, aY, aZ, mErrorTexture, false);
+ return true;
+ }
+ }
+}
diff --git a/src/main/java/gregtech/common/render/IRenderedBlockSideCheck.java b/src/main/java/gregtech/common/render/IRenderedBlockSideCheck.java
new file mode 100644
index 0000000000..8feb69b2f5
--- /dev/null
+++ b/src/main/java/gregtech/common/render/IRenderedBlockSideCheck.java
@@ -0,0 +1,15 @@
+package gregtech.common.render;
+
+import net.minecraft.block.Block;
+import net.minecraft.client.renderer.RenderBlocks;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+public interface IRenderedBlockSideCheck {
+
+ /** returning false stops all the other Rendering from happening on that Side. */
+ @SideOnly(Side.CLIENT)
+ boolean renderFullBlockSide(Block aBlock, RenderBlocks aRenderer, ForgeDirection side);
+}
diff --git a/src/main/java/gregtech/common/render/MultiTileBasicRender.java b/src/main/java/gregtech/common/render/MultiTileBasicRender.java
new file mode 100644
index 0000000000..be41739401
--- /dev/null
+++ b/src/main/java/gregtech/common/render/MultiTileBasicRender.java
@@ -0,0 +1,10 @@
+package gregtech.common.render;
+
+import net.minecraftforge.common.util.ForgeDirection;
+
+import gregtech.api.interfaces.ITexture;
+
+public interface MultiTileBasicRender {
+
+ ITexture getTexture(ForgeDirection side);
+}
diff --git a/src/main/java/gregtech/common/render/items/CosmicNeutroniumRenderer.java b/src/main/java/gregtech/common/render/items/CosmicNeutroniumRenderer.java
new file mode 100644
index 0000000000..acb830de58
--- /dev/null
+++ b/src/main/java/gregtech/common/render/items/CosmicNeutroniumRenderer.java
@@ -0,0 +1,109 @@
+package gregtech.common.render.items;
+
+import static gregtech.common.render.GT_RenderUtil.colorGTItem;
+
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.client.renderer.entity.RenderItem;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.IIcon;
+import net.minecraftforge.client.IItemRenderer;
+
+import org.lwjgl.opengl.GL11;
+import org.lwjgl.opengl.GL12;
+
+import com.gtnewhorizons.modularui.api.math.Pos2d;
+
+import gregtech.api.enums.Textures;
+import gregtech.common.render.GT_RenderUtil;
+
+public class CosmicNeutroniumRenderer extends GT_GeneratedMaterial_Renderer {
+
+ // spotless:off
+ private static final Pos2d point0 = new Pos2d(0 - 10, 0 - 10);
+ private static final Pos2d point1 = new Pos2d(17 + 10, 0 - 10);
+ private static final Pos2d point2 = new Pos2d(17 + 10, 17 + 10);
+ private static final Pos2d point3 = new Pos2d(0 - 10, 17 + 10);
+ // spotless:on
+
+ // TODO: Render halo outside of inventory.
+ private void drawHalo(ItemRenderType type) {
+ // Because when this class is instantiated, making this a static field will cause it to set to null.
+ final IIcon haloFuzzy = Textures.ItemIcons.HALO_FUZZY.getIcon();
+
+ if (haloFuzzy == null) {
+ return;
+ }
+
+ markNeedsAnimationUpdate(haloFuzzy);
+ GL11.glPushMatrix();
+
+ // Ideally this magic haloColour number should scale depending on the # of transparent pixels,
+ // but I'm not sure how to determine this with OpenGL.
+ // This is from Avaritia code, but modified to untangle the interfaces.
+ int haloColour = 0x4DFFFFFF;
+ float ca = (float) (haloColour >> 24 & 255) / 255.0F;
+ float cr = (float) (0x99FFFFFF >> 16 & 255) / 255.0F;
+ float cg = (float) (0x99FFFFFF >> 8 & 255) / 255.0F;
+ float cb = (float) (0x99FFFFFF & 255) / 255.0F;
+ GL11.glColor4f(cr, cg, cb, ca);
+
+ // spotless:off
+ // For those following in my footsteps, this may be of use - Colen 25th dec 2022.
+ // http://greyminecraftcoder.blogspot.com/2013/08/the-tessellator.html
+
+ Tessellator t = Tessellator.instance;
+
+ if (type.equals(IItemRenderer.ItemRenderType.INVENTORY)) {
+ t.startDrawingQuads();
+ t.addVertexWithUV(point0.x, point0.y, 0, haloFuzzy.getMinU(), haloFuzzy.getMinV());
+ t.addVertexWithUV(point3.x, point3.y, 0, haloFuzzy.getMinU(), haloFuzzy.getMaxV());
+ t.addVertexWithUV(point2.x, point2.y, 0, haloFuzzy.getMaxU(), haloFuzzy.getMaxV());
+ t.addVertexWithUV(point1.x, point1.y, 0, haloFuzzy.getMaxU(), haloFuzzy.getMinV());
+ t.draw();
+ }
+
+ GL11.glPopMatrix();
+ }
+
+ @Override
+ protected void renderRegularItem(ItemRenderType type, ItemStack item, IIcon icon, boolean shouldModulateColor, int pass, Object... data) {
+ RenderItem r = RenderItem.getInstance();
+
+ GL11.glPushMatrix();
+
+ if (type.equals(IItemRenderer.ItemRenderType.INVENTORY)) {
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GL11.glDisable(GL11.GL_ALPHA_TEST);
+ GL11.glDisable(GL11.GL_DEPTH_TEST);
+ }
+
+ if (pass == 0) {
+ drawHalo(type);
+ }
+
+ //spotless:on
+ {
+ // Draw actual cosmic Nt item.
+ GL11.glPushMatrix();
+
+ colorGTItem(item);
+
+ if (type.equals(IItemRenderer.ItemRenderType.INVENTORY)) {
+ GT_RenderUtil.renderItemIcon(icon, 16.0D, 0.001D, 0.0F, 0.0F, -1.0F);
+ } else {
+ GL11.glEnable(GL11.GL_DEPTH_TEST);
+ GT_RenderUtil.renderItem(type, icon);
+ }
+ GL11.glPopMatrix();
+ }
+
+ // GL11.glEnable(GL11.GL_ALPHA_TEST);
+ GL11.glEnable(GL12.GL_RESCALE_NORMAL);
+ GL11.glEnable(GL11.GL_DEPTH_TEST);
+
+ r.renderWithColor = true;
+
+ GL11.glPopMatrix();
+ }
+}
diff --git a/src/main/java/gregtech/common/render/items/GT_DataStick_Renderer.java b/src/main/java/gregtech/common/render/items/GT_DataStick_Renderer.java
new file mode 100644
index 0000000000..668b1daa6c
--- /dev/null
+++ b/src/main/java/gregtech/common/render/items/GT_DataStick_Renderer.java
@@ -0,0 +1,42 @@
+package gregtech.common.render.items;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.RenderHelper;
+import net.minecraft.client.renderer.entity.RenderItem;
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.client.IItemRenderer;
+
+import org.lwjgl.input.Keyboard;
+import org.lwjgl.opengl.GL11;
+
+import gregtech.api.util.GT_AssemblyLineUtils;
+
+// borrow form ae2
+
+public class GT_DataStick_Renderer implements IItemRenderer {
+
+ private final RenderItem ri = new RenderItem();
+
+ @Override
+ public boolean handleRenderType(ItemStack item, ItemRenderType type) {
+ final boolean isShiftHeld = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT);
+ return type == ItemRenderType.INVENTORY && isShiftHeld;
+ }
+
+ @Override
+ public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) {
+ return false;
+ }
+
+ @Override
+ public void renderItem(ItemRenderType type, ItemStack item, Object... data) {
+ final ItemStack is = GT_AssemblyLineUtils.getDataStickOutput(item);
+ final Minecraft mc = Minecraft.getMinecraft();
+
+ GL11.glPushAttrib(GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT);
+ RenderHelper.enableGUIStandardItemLighting();
+ this.ri.renderItemAndEffectIntoGUI(mc.fontRenderer, mc.getTextureManager(), is, 0, 0);
+ RenderHelper.disableStandardItemLighting();
+ GL11.glPopAttrib();
+ }
+}
diff --git a/src/main/java/gregtech/common/render/items/GT_GeneratedItem_Renderer.java b/src/main/java/gregtech/common/render/items/GT_GeneratedItem_Renderer.java
new file mode 100644
index 0000000000..84045446c2
--- /dev/null
+++ b/src/main/java/gregtech/common/render/items/GT_GeneratedItem_Renderer.java
@@ -0,0 +1,166 @@
+package gregtech.common.render.items;
+
+import static gregtech.api.enums.ItemList.Large_Fluid_Cell_Aluminium;
+import static gregtech.api.enums.ItemList.Large_Fluid_Cell_Chrome;
+import static gregtech.api.enums.ItemList.Large_Fluid_Cell_Iridium;
+import static gregtech.api.enums.ItemList.Large_Fluid_Cell_Neutronium;
+import static gregtech.api.enums.ItemList.Large_Fluid_Cell_Osmium;
+import static gregtech.api.enums.ItemList.Large_Fluid_Cell_StainlessSteel;
+import static gregtech.api.enums.ItemList.Large_Fluid_Cell_Steel;
+import static gregtech.api.enums.ItemList.Large_Fluid_Cell_Titanium;
+import static gregtech.api.enums.ItemList.Large_Fluid_Cell_TungstenSteel;
+import static gregtech.api.enums.Mods.HodgePodge;
+
+import javax.annotation.Nullable;
+
+import net.minecraft.client.Minecraft;
+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 com.mitchej123.hodgepodge.textures.IPatchedTextureAtlasSprite;
+
+import gregtech.api.enums.ItemList;
+import gregtech.api.enums.Textures;
+import gregtech.api.items.GT_MetaGenerated_Item;
+import gregtech.api.util.GT_Utility;
+import gregtech.common.render.GT_RenderUtil;
+import gregtech.loaders.ExtraIcons;
+
+public class GT_GeneratedItem_Renderer implements IItemRenderer {
+
+ @Override
+ public boolean handleRenderType(ItemStack item, ItemRenderType type) {
+ return type == ItemRenderType.EQUIPPED || type == ItemRenderType.EQUIPPED_FIRST_PERSON
+ || type == ItemRenderType.INVENTORY
+ || type == ItemRenderType.ENTITY;
+ }
+
+ @Override
+ public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) {
+ return type == ItemRenderType.ENTITY && helper == ItemRendererHelper.ENTITY_BOBBING
+ || (helper == ItemRendererHelper.ENTITY_ROTATION && Minecraft.getMinecraft().gameSettings.fancyGraphics);
+ }
+
+ @Override
+ public void renderItem(ItemRenderType type, ItemStack aStack, Object... data) {
+ short aMetaData = (short) aStack.getItemDamage();
+ if (!(aStack.getItem() instanceof GT_MetaGenerated_Item aItem)) return;
+
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glColor3f(1.0F, 1.0F, 1.0F);
+ IIcon tIcon;
+ if (aItem.mIconList[(aMetaData - aItem.mOffset)].length > 1) {
+ Long[] tStats = aItem.mElectricStats.get(aMetaData);
+
+ if ((tStats != null) && (tStats[3] < 0L)) {
+ long tCharge = aItem.getRealCharge(aStack);
+
+ if (tCharge <= 0L) {
+ tIcon = aItem.mIconList[(aMetaData - aItem.mOffset)][1];
+ } else {
+
+ if (tCharge >= tStats[0]) {
+ tIcon = aItem.mIconList[(aMetaData - aItem.mOffset)][8];
+ } else {
+ tIcon = aItem.mIconList[(aMetaData - aItem.mOffset)][(7
+ - (int) Math.max(0L, Math.min(5L, (tStats[0] - tCharge) * 6L / tStats[0])))];
+ }
+ }
+ } else {
+ tIcon = aItem.mIconList[(aMetaData - aItem.mOffset)][0];
+ }
+ } else {
+ tIcon = aItem.mIconList[(aMetaData - aItem.mOffset)][0];
+ }
+
+ if (tIcon == null) tIcon = Textures.ItemIcons.RENDERING_ERROR.getIcon();
+
+ markNeedsAnimationUpdate(tIcon);
+
+ ItemList largeFluidCell = getLargeFluidCell(aStack);
+ if (largeFluidCell != null) {
+ renderLargeFluidCellExtraParts(type, largeFluidCell, aStack);
+ }
+
+ Minecraft.getMinecraft().renderEngine.bindTexture(TextureMap.locationItemsTexture);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GT_RenderUtil.renderItem(type, tIcon);
+ GL11.glDisable(GL11.GL_BLEND);
+ }
+
+ @Nullable
+ private static ItemList getLargeFluidCell(ItemStack stack) {
+ if (isSame(Large_Fluid_Cell_Steel, stack)) return Large_Fluid_Cell_Steel;
+ if (isSame(Large_Fluid_Cell_Aluminium, stack)) return Large_Fluid_Cell_Aluminium;
+ if (isSame(Large_Fluid_Cell_TungstenSteel, stack)) return Large_Fluid_Cell_TungstenSteel;
+ if (isSame(Large_Fluid_Cell_StainlessSteel, stack)) return Large_Fluid_Cell_StainlessSteel;
+ if (isSame(Large_Fluid_Cell_Titanium, stack)) return Large_Fluid_Cell_Titanium;
+ if (isSame(Large_Fluid_Cell_Chrome, stack)) return Large_Fluid_Cell_Chrome;
+ if (isSame(Large_Fluid_Cell_Iridium, stack)) return Large_Fluid_Cell_Iridium;
+ if (isSame(Large_Fluid_Cell_Osmium, stack)) return Large_Fluid_Cell_Osmium;
+ if (isSame(Large_Fluid_Cell_Neutronium, stack)) return Large_Fluid_Cell_Neutronium;
+
+ return null;
+ }
+
+ private void renderLargeFluidCellExtraParts(IItemRenderer.ItemRenderType type, ItemList item, ItemStack stack) {
+
+ IIcon inner = switch (item) {
+ case Large_Fluid_Cell_Steel -> ExtraIcons.steelLargeCellInner;
+ case Large_Fluid_Cell_Aluminium -> ExtraIcons.aluminiumLargeCellInner;
+ case Large_Fluid_Cell_StainlessSteel -> ExtraIcons.stainlesssteelLargeCellInner;
+ case Large_Fluid_Cell_Titanium -> ExtraIcons.titaniumLargeCellInner;
+ case Large_Fluid_Cell_TungstenSteel -> ExtraIcons.tungstensteelLargeCellInner;
+ case Large_Fluid_Cell_Iridium -> ExtraIcons.iridiumLargeCellInner;
+ case Large_Fluid_Cell_Osmium -> ExtraIcons.osmiumLargeCellInner;
+ case Large_Fluid_Cell_Chrome -> ExtraIcons.chromiumLargeCellInner;
+ case Large_Fluid_Cell_Neutronium -> ExtraIcons.neutroniumLargeCellInner;
+ default -> Textures.ItemIcons.RENDERING_ERROR.getIcon();
+ };
+
+ // Empty inner side
+ Minecraft.getMinecraft().renderEngine.bindTexture(TextureMap.locationItemsTexture);
+ markNeedsAnimationUpdate(inner);
+ GT_RenderUtil.renderItem(type, inner);
+
+ FluidStack fluidStack = GT_Utility.getFluidForFilledItem(stack, true);
+
+ if (fluidStack != null && fluidStack.getFluid() != null) {
+ IIcon fluidIcon = fluidStack.getFluid()
+ .getIcon(fluidStack);
+ if (fluidIcon == null) {
+ fluidIcon = Textures.ItemIcons.RENDERING_ERROR.getIcon();
+ }
+ int fluidColor = fluidStack.getFluid()
+ .getColor(fluidStack);
+
+ Minecraft.getMinecraft().renderEngine.bindTexture(TextureMap.locationBlocksTexture);
+ markNeedsAnimationUpdate(fluidIcon);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GL11.glDepthFunc(GL11.GL_EQUAL);
+ GL11.glColor3ub((byte) (fluidColor >> 16), (byte) (fluidColor >> 8), (byte) fluidColor);
+ GT_RenderUtil.renderItem(type, fluidIcon);
+
+ GL11.glColor3ub((byte) -1, (byte) -1, (byte) -1);
+ GL11.glDepthFunc(GL11.GL_LEQUAL);
+ }
+ }
+
+ private static boolean isSame(ItemList item, ItemStack stack) {
+ ItemStack internal = item.getInternalStack_unsafe();
+ if (GT_Utility.isStackInvalid(internal)) return false;
+
+ return internal.getItem() == stack.getItem() && internal.getItemDamage() == stack.getItemDamage();
+ }
+
+ protected void markNeedsAnimationUpdate(IIcon icon) {
+ if (HodgePodge.isModLoaded() && icon instanceof IPatchedTextureAtlasSprite) {
+ ((IPatchedTextureAtlasSprite) icon).markNeedsAnimationUpdate();
+ }
+ }
+}
diff --git a/src/main/java/gregtech/common/render/items/GT_GeneratedMaterial_Renderer.java b/src/main/java/gregtech/common/render/items/GT_GeneratedMaterial_Renderer.java
new file mode 100644
index 0000000000..a67d5512ed
--- /dev/null
+++ b/src/main/java/gregtech/common/render/items/GT_GeneratedMaterial_Renderer.java
@@ -0,0 +1,130 @@
+package gregtech.common.render.items;
+
+import static gregtech.api.enums.Mods.HodgePodge;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.IIcon;
+import net.minecraftforge.client.IItemRenderer;
+import net.minecraftforge.fluids.Fluid;
+import net.minecraftforge.fluids.FluidStack;
+
+import org.lwjgl.opengl.GL11;
+
+import com.mitchej123.hodgepodge.textures.IPatchedTextureAtlasSprite;
+
+import codechicken.lib.render.TextureUtils;
+import gregtech.api.interfaces.IGT_ItemWithMaterialRenderer;
+import gregtech.api.util.GT_Utility;
+import gregtech.common.render.GT_RenderUtil;
+
+public class GT_GeneratedMaterial_Renderer implements IItemRenderer {
+
+ @Override
+ public boolean handleRenderType(ItemStack item, ItemRenderType type) {
+ return type == ItemRenderType.EQUIPPED || type == ItemRenderType.EQUIPPED_FIRST_PERSON
+ || type == ItemRenderType.INVENTORY
+ || type == ItemRenderType.ENTITY;
+ }
+
+ @Override
+ public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) {
+ return type == ItemRenderType.ENTITY && helper == ItemRendererHelper.ENTITY_BOBBING
+ || (helper == ItemRendererHelper.ENTITY_ROTATION && Minecraft.getMinecraft().gameSettings.fancyGraphics);
+ }
+
+ /**
+ * Handle special fluid display rendering. Return false if does not need such kind of handling. Note: annotations
+ * should not be rendered here. Only render the fluid texture. Parameters are values passed from
+ * {@link IItemRenderer#renderItem(ItemRenderType, ItemStack, Object...)} verbatim. Do not modify the argument.
+ * <p>
+ * While this is called, BLEND and ALPHA_TEST is on. It is expected that these remain enabled while exit.
+ *
+ * @return true if did special fluid display rendering. false otherwise.
+ */
+ public boolean renderFluidDisplayItem(ItemRenderType type, ItemStack aStack, Object... data) {
+ return false;
+ }
+
+ @Override
+ public void renderItem(ItemRenderType type, ItemStack aStack, Object... data) {
+ short aMetaData = (short) aStack.getItemDamage();
+ if (!(aStack.getItem() instanceof IGT_ItemWithMaterialRenderer aItem)) return;
+
+ int passes = 1;
+ if (aItem.requiresMultipleRenderPasses()) {
+ passes = aItem.getRenderPasses(aMetaData);
+ }
+
+ for (int pass = 0; pass < passes; pass++) {
+ IIcon tIcon = aItem.getIcon(aMetaData, pass);
+ IIcon tOverlay = aItem.getOverlayIcon(aMetaData, pass);
+ FluidStack aFluid = GT_Utility.getFluidForFilledItem(aStack, true);
+
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GL11.glEnable(GL11.GL_ALPHA_TEST);
+
+ if (tIcon != null) {
+ markNeedsAnimationUpdate(tIcon);
+ renderRegularItem(type, aStack, tIcon, aFluid == null, pass, data);
+ }
+
+ if (tOverlay != null && aFluid != null && aFluid.getFluid() != null) {
+ IIcon fluidIcon = aFluid.getFluid()
+ .getIcon(aFluid);
+ if (fluidIcon != null) {
+ markNeedsAnimationUpdate(fluidIcon);
+ // Adds colour to a cells fluid. Does not colour full fluid icons as shown in NEI etc.
+ renderContainedFluid(type, aFluid, fluidIcon);
+ }
+ }
+
+ if (tOverlay != null) {
+ GL11.glColor3f(1.0F, 1.0F, 1.0F);
+ TextureUtils.bindAtlas(aItem.getSpriteNumber());
+ markNeedsAnimationUpdate(tOverlay);
+ renderItemOverlay(type, tOverlay);
+ }
+
+ GL11.glDisable(GL11.GL_BLEND);
+ }
+ }
+
+ protected void renderRegularItem(ItemRenderType type, ItemStack aStack, IIcon icon, boolean shouldModulateColor,
+ int pass, Object... data) {
+ renderRegularItem(type, aStack, icon, shouldModulateColor);
+ }
+
+ protected void renderRegularItem(ItemRenderType type, ItemStack aStack, IIcon icon, boolean shouldModulateColor) {
+ if (!(aStack.getItem() instanceof IGT_ItemWithMaterialRenderer aItem)) return;
+
+ if (shouldModulateColor) {
+ short[] tModulation = aItem.getRGBa(aStack);
+ GL11.glColor3f(tModulation[0] / 255.0F, tModulation[1] / 255.0F, tModulation[2] / 255.0F);
+ }
+
+ GT_RenderUtil.renderItem(type, icon);
+ }
+
+ protected void renderContainedFluid(ItemRenderType type, FluidStack aFluidStack, IIcon fluidIcon) {
+ Fluid aFluid = aFluidStack.getFluid();
+ int tColor = aFluid.getColor(aFluidStack);
+ GL11.glColor3f((tColor >> 16 & 0xFF) / 255.0F, (tColor >> 8 & 0xFF) / 255.0F, (tColor & 0xFF) / 255.0F);
+ TextureUtils.bindAtlas(aFluid.getSpriteNumber());
+
+ GL11.glDepthFunc(GL11.GL_EQUAL);
+ GT_RenderUtil.renderItem(type, fluidIcon);
+ GL11.glDepthFunc(GL11.GL_LEQUAL);
+ }
+
+ protected void renderItemOverlay(ItemRenderType type, IIcon overlay) {
+ GT_RenderUtil.renderItem(type, overlay);
+ }
+
+ protected void markNeedsAnimationUpdate(IIcon icon) {
+ if (HodgePodge.isModLoaded() && icon instanceof IPatchedTextureAtlasSprite) {
+ ((IPatchedTextureAtlasSprite) icon).markNeedsAnimationUpdate();
+ }
+ }
+}
diff --git a/src/main/java/gregtech/common/render/items/GT_MetaGenerated_Item_Renderer.java b/src/main/java/gregtech/common/render/items/GT_MetaGenerated_Item_Renderer.java
new file mode 100644
index 0000000000..d7425c2fcb
--- /dev/null
+++ b/src/main/java/gregtech/common/render/items/GT_MetaGenerated_Item_Renderer.java
@@ -0,0 +1,85 @@
+package gregtech.common.render.items;
+
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.client.IItemRenderer;
+import net.minecraftforge.client.MinecraftForgeClient;
+
+import gregtech.api.enums.ItemList;
+import gregtech.api.enums.Materials;
+import gregtech.api.interfaces.IGT_ItemWithMaterialRenderer;
+import gregtech.api.objects.ItemData;
+import gregtech.api.util.GT_OreDictUnificator;
+import gregtech.api.util.GT_Utility;
+import gregtech.common.render.GT_RenderUtil;
+
+public class GT_MetaGenerated_Item_Renderer implements IItemRenderer {
+
+ private final IItemRenderer mItemRenderer = new GT_GeneratedItem_Renderer();
+ private final IItemRenderer mMaterialRenderer = new GT_GeneratedMaterial_Renderer();
+
+ private final IItemRenderer mDataStickRenderer = new GT_DataStick_Renderer();
+
+ public GT_MetaGenerated_Item_Renderer() {}
+
+ public <T extends Item & IGT_ItemWithMaterialRenderer> void registerItem(T item) {
+ MinecraftForgeClient.registerItemRenderer(item, this);
+ }
+
+ @Override
+ public boolean handleRenderType(ItemStack aStack, ItemRenderType aType) {
+ if ((GT_Utility.isStackInvalid(aStack)) || (aStack.getItemDamage() < 0)
+ || !(aStack.getItem() instanceof IGT_ItemWithMaterialRenderer)
+ || !((IGT_ItemWithMaterialRenderer) aStack.getItem()).shouldUseCustomRenderer(aStack.getItemDamage())) {
+ return false;
+ }
+ return getRendererForItemStack(aStack).handleRenderType(aStack, aType);
+ }
+
+ @Override
+ public boolean shouldUseRenderHelper(ItemRenderType aType, ItemStack aStack, ItemRendererHelper aHelper) {
+ if (GT_Utility.isStackInvalid(aStack)) {
+ return false;
+ }
+ return getRendererForItemStack(aStack).shouldUseRenderHelper(aType, aStack, aHelper);
+ }
+
+ @Override
+ public void renderItem(ItemRenderType type, ItemStack aStack, Object... data) {
+ GT_RenderUtil.applyStandardItemTransform(type);
+
+ IItemRenderer itemRenderer = getRendererForItemStack(aStack);
+ itemRenderer.renderItem(type, aStack, data);
+ }
+
+ private IItemRenderer getRendererForItemStack(ItemStack aStack) {
+ short aMetaData = (short) aStack.getItemDamage();
+ IGT_ItemWithMaterialRenderer aItem = (IGT_ItemWithMaterialRenderer) aStack.getItem();
+
+ if (aItem != null && aItem.allowMaterialRenderer(aMetaData)) {
+ IItemRenderer aMaterialRenderer = aItem.getMaterialRenderer(aMetaData);
+
+ // Handle fluid rendering.
+ if (aMaterialRenderer == null) {
+ ItemData itemData = GT_OreDictUnificator.getAssociation(aStack);
+ if (itemData != null) {
+ Materials material = itemData.mMaterial.mMaterial;
+ if (material.renderer != null) {
+ aMaterialRenderer = material.renderer;
+ }
+ }
+ }
+
+ return aMaterialRenderer != null ? aMaterialRenderer : mMaterialRenderer;
+ }
+
+ // handle data stick
+ if (aStack.getItem() == ItemList.Tool_DataStick.getItem() && aStack.hasTagCompound()
+ && aStack.getTagCompound()
+ .hasKey("output")) {
+ return mDataStickRenderer;
+ }
+
+ return mItemRenderer;
+ }
+}
diff --git a/src/main/java/gregtech/common/render/items/GaiaSpiritRenderer.java b/src/main/java/gregtech/common/render/items/GaiaSpiritRenderer.java
new file mode 100644
index 0000000000..08663adf4d
--- /dev/null
+++ b/src/main/java/gregtech/common/render/items/GaiaSpiritRenderer.java
@@ -0,0 +1,27 @@
+package gregtech.common.render.items;
+
+import java.awt.Color;
+
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.IIcon;
+
+import org.lwjgl.opengl.GL11;
+
+import gregtech.GT_Mod;
+import gregtech.common.render.GT_RenderUtil;
+
+public class GaiaSpiritRenderer extends GT_GeneratedMaterial_Renderer {
+
+ @Override
+ protected void renderRegularItem(ItemRenderType type, ItemStack aStack, IIcon icon, boolean shouldModulateColor) {
+ long animationTicks = GT_Mod.gregtechproxy.getAnimationTicks();
+ float partialTicks = GT_Mod.gregtechproxy.getPartialRenderTicks();
+
+ if (shouldModulateColor) {
+ Color color = Color.getHSBColor((animationTicks % 360 + partialTicks) % 180 / 180f, 0.4f, 0.9f);
+ GL11.glColor3f(color.getRed() / 255.0F, color.getGreen() / 255.0F, color.getBlue() / 255.0F);
+ }
+
+ GT_RenderUtil.renderItem(type, icon);
+ }
+}
diff --git a/src/main/java/gregtech/common/render/items/InfinityRenderer.java b/src/main/java/gregtech/common/render/items/InfinityRenderer.java
new file mode 100644
index 0000000000..3a98898b8a
--- /dev/null
+++ b/src/main/java/gregtech/common/render/items/InfinityRenderer.java
@@ -0,0 +1,139 @@
+package gregtech.common.render.items;
+
+import java.util.Random;
+
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.IIcon;
+import net.minecraftforge.fluids.FluidStack;
+
+import org.lwjgl.opengl.GL11;
+
+import codechicken.lib.render.TextureUtils;
+import gregtech.api.enums.Textures;
+import gregtech.api.interfaces.IGT_ItemWithMaterialRenderer;
+import gregtech.api.util.GT_Utility;
+
+// TODO: Render effects outside inventory.
+
+public class InfinityRenderer extends GT_GeneratedMaterial_Renderer {
+
+ public Random rand = new Random();
+
+ @Override
+ public void renderItem(ItemRenderType type, ItemStack aStack, Object... data) {
+ short aMetaData = (short) aStack.getItemDamage();
+ if (!(aStack.getItem() instanceof IGT_ItemWithMaterialRenderer aItem)) return;
+
+ int passes = 1;
+ if (aItem.requiresMultipleRenderPasses()) {
+ passes = aItem.getRenderPasses(aMetaData);
+ }
+
+ for (int pass = 0; pass < passes; pass++) {
+ IIcon tIcon = aItem.getIcon(aMetaData, pass);
+ IIcon tOverlay = aItem.getOverlayIcon(aMetaData, pass);
+ FluidStack aFluid = GT_Utility.getFluidForFilledItem(aStack, true);
+
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GL11.glEnable(GL11.GL_ALPHA_TEST);
+
+ if (type == ItemRenderType.INVENTORY) {
+ if (pass == 0) {
+ renderHalo();
+ }
+ renderPulse(tOverlay, tIcon);
+ }
+
+ // Workaround for cell and comb:
+ // 1. BW capsule needs `renderContainedFluid` call as it doesn't have
+ // `materialicons/CUSTOM/infinity/capsuleMolten`
+ // 2. Without these 2 GL calls fluid texture leaks out of the cell / capsule
+ // 3. Comb texture doesn't like depth enabled
+ if (passes == 1) {
+ GL11.glEnable(GL11.GL_DEPTH_TEST);
+ }
+ GL11.glEnable(GL11.GL_ALPHA_TEST);
+
+ if (tIcon != null) {
+ markNeedsAnimationUpdate(tIcon);
+ renderRegularItem(type, aStack, tIcon, aFluid == null);
+ }
+
+ if (tOverlay != null && aFluid != null && aFluid.getFluid() != null) {
+ IIcon fluidIcon = aFluid.getFluid()
+ .getIcon(aFluid);
+ if (fluidIcon != null) {
+ markNeedsAnimationUpdate(fluidIcon);
+ // Adds colour to a cells fluid. Does not colour full fluid icons as shown in NEI etc.
+ renderContainedFluid(type, aFluid, fluidIcon);
+ }
+ }
+
+ if (tOverlay != null) {
+ GL11.glColor3f(1.0F, 1.0F, 1.0F);
+ TextureUtils.bindAtlas(aItem.getSpriteNumber());
+ markNeedsAnimationUpdate(tOverlay);
+ renderItemOverlay(type, tOverlay);
+ }
+
+ GL11.glDisable(GL11.GL_BLEND);
+ }
+ }
+
+ private void renderHalo() {
+ GL11.glPushMatrix();
+ IIcon halo = Textures.ItemIcons.HALO.getIcon();
+
+ int spread = 10;
+ int haloAlpha = 0xFF000000;
+
+ if (halo == null) {
+ return;
+ }
+
+ Tessellator t = Tessellator.instance;
+
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+
+ GL11.glDisable(GL11.GL_ALPHA_TEST);
+ GL11.glDisable(GL11.GL_DEPTH_TEST);
+
+ GL11.glColor4f(20 / 255.0f, 20 / 255.0f, 20 / 255.0f, (float) (haloAlpha >> 24 & 255) / 255.0F);
+
+ t.startDrawingQuads();
+ t.addVertexWithUV(-spread, -spread, 0, halo.getMinU(), halo.getMinV());
+ t.addVertexWithUV(-spread, 16 + spread, 0, halo.getMinU(), halo.getMaxV());
+ t.addVertexWithUV(16 + spread, 16 + spread, 0, halo.getMaxU(), halo.getMaxV());
+ t.addVertexWithUV(16 + spread, -spread, 0, halo.getMaxU(), halo.getMinV());
+ t.draw();
+ GL11.glPopMatrix();
+ }
+
+ private void renderPulse(IIcon... icons) {
+ Tessellator t = Tessellator.instance;
+ double random = rand.nextGaussian();
+ double scale = (random * 0.15) + 0.95;
+ double offset = (1.0 - scale) / 2.0;
+
+ for (IIcon icon : icons) {
+ if (icon == null) continue;
+ GL11.glPushMatrix();
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glTranslated(offset * 16.0, offset * 16.0, 1.0);
+ GL11.glScaled(scale, scale, 1.0);
+
+ t.startDrawingQuads();
+ t.setColorRGBA_F(1.0f, 1.0f, 1.0f, 0.6f);
+ t.addVertexWithUV(0 - offset, 0 - offset, 0, icon.getMinU(), icon.getMinV());
+ t.addVertexWithUV(0 - offset, 16 + offset, 0, icon.getMinU(), icon.getMaxV());
+ t.addVertexWithUV(16 + offset, 16 + offset, 0, icon.getMaxU(), icon.getMaxV());
+ t.addVertexWithUV(16 + offset, 0 - offset, 0, icon.getMaxU(), icon.getMinV());
+ t.draw();
+
+ GL11.glPopMatrix();
+ }
+ }
+}
diff --git a/src/main/java/gregtech/common/render/items/TranscendentMetalRenderer.java b/src/main/java/gregtech/common/render/items/TranscendentMetalRenderer.java
new file mode 100644
index 0000000000..8583033e0f
--- /dev/null
+++ b/src/main/java/gregtech/common/render/items/TranscendentMetalRenderer.java
@@ -0,0 +1,145 @@
+package gregtech.common.render.items;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.ItemRenderer;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.client.renderer.entity.RenderItem;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.IIcon;
+import net.minecraftforge.client.IItemRenderer;
+import net.minecraftforge.fluids.Fluid;
+import net.minecraftforge.fluids.FluidStack;
+
+import org.lwjgl.opengl.GL11;
+
+import codechicken.lib.render.TextureUtils;
+import gregtech.GT_Mod;
+import gregtech.api.interfaces.IGT_ItemWithMaterialRenderer;
+import gregtech.api.util.GT_Util;
+
+public class TranscendentMetalRenderer extends GT_GeneratedMaterial_Renderer {
+
+ @Override
+ public void renderItem(ItemRenderType type, ItemStack aStack, Object... data) {
+ if (type == ItemRenderType.ENTITY) {
+ // Pretend fancy graphics is enabled
+ if (!Minecraft.getMinecraft().gameSettings.fancyGraphics) {
+ if (RenderItem.renderInFrame) {
+ GL11.glRotatef(180.0F, 0.0F, 1.0F, 0.0F);
+ }
+ // Magic numbers calculated from vanilla code
+ GL11.glTranslatef(-0.5F, -0.25F, 0.0421875F);
+ }
+ }
+ super.renderItem(type, aStack, data);
+ }
+
+ @Override
+ protected void renderRegularItem(ItemRenderType type, ItemStack itemStack, IIcon icon,
+ boolean shouldModulateColor) {
+
+ if (!(itemStack.getItem() instanceof final IGT_ItemWithMaterialRenderer itemRenderer)) return;
+
+ GL11.glPushMatrix();
+ applyEffect(type, itemRenderer.getRGBa(itemStack), shouldModulateColor);
+
+ if (shouldModulateColor) {
+ short[] tModulation = itemRenderer.getRGBa(itemStack);
+ GL11.glColor3f(tModulation[0] / 255.0F, tModulation[1] / 255.0F, tModulation[2] / 255.0F);
+ }
+
+ if (type.equals(IItemRenderer.ItemRenderType.INVENTORY)) {
+ GL11.glScalef(16, 16, 32);
+ }
+ ItemRenderer.renderItemIn2D(
+ Tessellator.instance,
+ icon.getMaxU(),
+ icon.getMinV(),
+ icon.getMinU(),
+ icon.getMaxV(),
+ icon.getIconWidth(),
+ icon.getIconHeight(),
+ 0.0625F);
+
+ GL11.glPopMatrix();
+ }
+
+ @Override
+ protected void renderContainedFluid(ItemRenderType type, FluidStack fluidStack, IIcon fluidIcon) {
+ GL11.glPushMatrix();
+
+ Fluid fluid = fluidStack.getFluid();
+ applyEffect(type, GT_Util.getRGBaArray(fluid.getColor()), true);
+
+ TextureUtils.bindAtlas(fluid.getSpriteNumber());
+ GL11.glDepthFunc(GL11.GL_EQUAL);
+ if (type.equals(IItemRenderer.ItemRenderType.INVENTORY)) {
+ GL11.glScalef(16, 16, 32);
+ }
+
+ ItemRenderer.renderItemIn2D(
+ Tessellator.instance,
+ fluidIcon.getMaxU(),
+ fluidIcon.getMinV(),
+ fluidIcon.getMinU(),
+ fluidIcon.getMaxV(),
+ fluidIcon.getIconWidth(),
+ fluidIcon.getIconHeight(),
+ 0.0625F);
+
+ GL11.glDepthFunc(GL11.GL_LEQUAL);
+ GL11.glPopMatrix();
+ }
+
+ @Override
+ protected void renderItemOverlay(ItemRenderType type, IIcon overlay) {
+ GL11.glPushMatrix();
+ applyEffect(type, null, false);
+
+ if (type.equals(IItemRenderer.ItemRenderType.INVENTORY)) {
+ GL11.glScalef(16, 16, 32);
+ }
+ ItemRenderer.renderItemIn2D(
+ Tessellator.instance,
+ overlay.getMaxU(),
+ overlay.getMinV(),
+ overlay.getMinU(),
+ overlay.getMaxV(),
+ overlay.getIconWidth(),
+ overlay.getIconHeight(),
+ 0.0625F);
+
+ GL11.glPopMatrix();
+ }
+
+ private void applyEffect(ItemRenderType type, short[] modulation, boolean shouldModulateColor) {
+ if (RenderItem.renderInFrame) {
+ // Float in front of item frame
+ GL11.glTranslatef(0.0f, 0.0f, -0.5f);
+ }
+
+ if (type.equals(IItemRenderer.ItemRenderType.INVENTORY)) {
+ GL11.glTranslatef(8f, 8f, 0f);
+ } else {
+ GL11.glTranslatef(0.5f, 0.5f, 0.0f);
+ }
+
+ GL11.glRotatef((GT_Mod.gregtechproxy.getAnimationTicks() * 3.5f) % 360, 0.3f, 0.5f, 0.2f);
+ GL11.glRotatef(180, 0.5f, 0.0f, 0.0f);
+
+ if (type.equals(IItemRenderer.ItemRenderType.INVENTORY)) {
+ GL11.glTranslatef(-8f, -8f, 0f);
+ } else {
+ GL11.glTranslatef(-0.5f, -0.5f, 0.0f);
+ }
+
+ // Center on point of rotation
+ GL11.glTranslatef(0.0f, 0.0f, 0.03125F);
+
+ if (shouldModulateColor) {
+ GL11.glColor4f(modulation[0] / 255.0F, modulation[1] / 255.0F, modulation[2] / 255.0F, 255);
+ } else {
+ GL11.glColor4f(1f, 1f, 1f, 255);
+ }
+ }
+}
diff --git a/src/main/java/gregtech/common/render/items/UniversiumRenderer.java b/src/main/java/gregtech/common/render/items/UniversiumRenderer.java
new file mode 100644
index 0000000000..92b86071cf
--- /dev/null
+++ b/src/main/java/gregtech/common/render/items/UniversiumRenderer.java
@@ -0,0 +1,197 @@
+package gregtech.common.render.items;
+
+import static gregtech.api.enums.Mods.Avaritia;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.RenderHelper;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.client.renderer.entity.RenderItem;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.item.EntityItem;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.IIcon;
+import net.minecraft.util.MathHelper;
+import net.minecraft.util.ResourceLocation;
+
+import org.lwjgl.opengl.GL11;
+import org.lwjgl.opengl.GL12;
+import org.lwjgl.opengl.GL20;
+
+import codechicken.lib.render.TextureUtils;
+import fox.spiteful.avaritia.render.CosmicRenderShenanigans;
+import gregtech.api.enums.ItemList;
+import gregtech.api.interfaces.IGT_ItemWithMaterialRenderer;
+import gregtech.common.render.GT_RenderUtil;
+
+@SuppressWarnings("RedundantLabeledSwitchRuleCodeBlock")
+public class UniversiumRenderer extends GT_GeneratedMaterial_Renderer {
+
+ private static final float cosmicOpacity = 2.5f;
+
+ @Override
+ public boolean renderFluidDisplayItem(ItemRenderType type, ItemStack aStack, Object... data) {
+ Item item = aStack.getItem();
+ if (item == null) return false;
+
+ magicRenderMethod(
+ type,
+ ItemList.Emitter_UEV.get(1), // hack to make it render correctly
+ item.getIconFromDamage(aStack.getItemDamage()),
+ true,
+ data);
+ return true;
+ }
+
+ @Override
+ public void renderItem(ItemRenderType type, ItemStack aStack, Object... data) {
+ short aMetaData = (short) aStack.getItemDamage();
+ if (!(aStack.getItem() instanceof IGT_ItemWithMaterialRenderer aItem)) return;
+
+ int passes = 1;
+ if (aItem.requiresMultipleRenderPasses()) {
+ passes = aItem.getRenderPasses(aMetaData);
+ }
+
+ for (int pass = 0; pass < passes; pass++) {
+ IIcon tIcon = aItem.getIcon(aMetaData, pass);
+ IIcon tOverlay = aItem.getOverlayIcon(aMetaData, pass);
+
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GL11.glEnable(GL11.GL_ALPHA_TEST);
+
+ if (tIcon != null) {
+ markNeedsAnimationUpdate(tIcon);
+ magicRenderMethod(type, aStack, tIcon, false, data);
+ }
+
+ GL11.glDisable(GL11.GL_LIGHTING);
+
+ if (tOverlay != null) {
+ GL11.glColor3f(1.0F, 1.0F, 1.0F);
+ TextureUtils.bindAtlas(aItem.getSpriteNumber());
+ markNeedsAnimationUpdate(tOverlay);
+ renderItemOverlay(type, tOverlay);
+ }
+
+ GL11.glDisable(GL11.GL_BLEND);
+ }
+ }
+
+ private void magicRenderMethod(ItemRenderType type, ItemStack aStack, IIcon tIcon, boolean fluidDisplay,
+ Object... data) {
+ if (!Avaritia.isModLoaded()) {
+ return;
+ }
+
+ RenderItem r = RenderItem.getInstance();
+ Minecraft mc = Minecraft.getMinecraft();
+ Tessellator t = Tessellator.instance;
+ float minU = tIcon.getMinU();
+ float maxU = tIcon.getMaxU();
+ float minV = tIcon.getMinV();
+ float maxV = tIcon.getMaxV();
+
+ processLightLevel(type, data);
+
+ GL11.glPushMatrix();
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+
+ if (type == ItemRenderType.INVENTORY) {
+ RenderHelper.enableGUIStandardItemLighting();
+
+ GL11.glDisable(GL11.GL_ALPHA_TEST);
+ GL11.glDisable(GL11.GL_DEPTH_TEST);
+
+ if (fluidDisplay) {
+ // this somehow makes shader render correctly
+ ResourceLocation resourcelocation = mc.getTextureManager()
+ .getResourceLocation(aStack.getItemSpriteNumber());
+ mc.getTextureManager()
+ .bindTexture(resourcelocation);
+ } else {
+ GT_RenderUtil.renderItem(type, tIcon);
+ }
+
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ RenderHelper.enableGUIStandardItemLighting();
+
+ GL11.glDisable(GL11.GL_ALPHA_TEST);
+ GL11.glDisable(GL11.GL_DEPTH_TEST);
+
+ if (fluidDisplay) {
+ GL11.glDisable(GL11.GL_BLEND);
+ }
+
+ CosmicRenderShenanigans.cosmicOpacity = cosmicOpacity;
+ CosmicRenderShenanigans.inventoryRender = true;
+ CosmicRenderShenanigans.useShader();
+
+ GL11.glColor4d(1, 1, 1, 1);
+
+ // Draw cosmic overlay
+ GT_RenderUtil.renderItem(type, tIcon);
+
+ CosmicRenderShenanigans.releaseShader();
+ CosmicRenderShenanigans.inventoryRender = false;
+
+ GL11.glEnable(GL12.GL_RESCALE_NORMAL);
+ } else {
+ // RENDER ITEM
+ GT_RenderUtil.renderItem(type, tIcon);
+
+ int program = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM);
+
+ GL11.glDisable(GL11.GL_ALPHA_TEST);
+ GL11.glDepthFunc(GL11.GL_EQUAL);
+ CosmicRenderShenanigans.cosmicOpacity = cosmicOpacity;
+ CosmicRenderShenanigans.useShader();
+
+ // RENDER COSMIC OVERLAY
+ GT_RenderUtil.renderItem(type, tIcon);
+ CosmicRenderShenanigans.releaseShader();
+ GL11.glDepthFunc(GL11.GL_LEQUAL);
+
+ GL20.glUseProgram(program);
+ }
+
+ GL11.glEnable(GL11.GL_DEPTH_TEST);
+ GL11.glEnable(GL11.GL_ALPHA_TEST);
+ GL11.glDisable(GL11.GL_BLEND);
+ GL11.glPopMatrix();
+ }
+
+ private void processLightLevel(ItemRenderType type, Object... data) {
+ switch (type) {
+ case ENTITY -> {
+ EntityItem ent = (EntityItem) (data[1]);
+ if (ent != null) {
+ CosmicRenderShenanigans.setLightFromLocation(
+ ent.worldObj,
+ MathHelper.floor_double(ent.posX),
+ MathHelper.floor_double(ent.posY),
+ MathHelper.floor_double(ent.posZ));
+ }
+ }
+ case EQUIPPED, EQUIPPED_FIRST_PERSON -> {
+ EntityLivingBase ent = (EntityLivingBase) (data[1]);
+ if (ent != null) {
+ CosmicRenderShenanigans.setLightFromLocation(
+ ent.worldObj,
+ MathHelper.floor_double(ent.posX),
+ MathHelper.floor_double(ent.posY),
+ MathHelper.floor_double(ent.posZ));
+ }
+ }
+ case INVENTORY -> {
+ CosmicRenderShenanigans.setLightLevel(10.2f);
+ }
+ default -> {
+ CosmicRenderShenanigans.setLightLevel(1.0f);
+ }
+ }
+ }
+}