diff options
Diffstat (limited to 'src/main/java/gregtech/common/render')
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); + } + } + } +} |