001    package net.minecraft.client.renderer.entity;
002    
003    import cpw.mods.fml.relauncher.Side;
004    import cpw.mods.fml.relauncher.SideOnly;
005    import net.minecraft.block.Block;
006    import net.minecraft.client.gui.FontRenderer;
007    import net.minecraft.client.model.ModelBase;
008    import net.minecraft.client.model.ModelBiped;
009    import net.minecraft.client.renderer.RenderBlocks;
010    import net.minecraft.client.renderer.RenderEngine;
011    import net.minecraft.client.renderer.Tessellator;
012    import net.minecraft.entity.Entity;
013    import net.minecraft.entity.EntityLiving;
014    import net.minecraft.util.AxisAlignedBB;
015    import net.minecraft.util.MathHelper;
016    import net.minecraft.world.World;
017    import org.lwjgl.opengl.GL11;
018    
019    @SideOnly(Side.CLIENT)
020    public abstract class Render
021    {
022        protected RenderManager renderManager;
023        private ModelBase modelBase = new ModelBiped();
024        protected RenderBlocks renderBlocks = new RenderBlocks();
025        protected float shadowSize = 0.0F;
026    
027        /**
028         * Determines the darkness of the object's shadow. Higher value makes a darker shadow.
029         */
030        protected float shadowOpaque = 1.0F;
031    
032        /**
033         * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then
034         * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic
035         * (Render<T extends Entity) and this method has signature public void doRender(T entity, double d, double d1,
036         * double d2, float f, float f1). But JAD is pre 1.5 so doesn't do that.
037         */
038        public abstract void doRender(Entity var1, double var2, double var4, double var6, float var8, float var9);
039    
040        /**
041         * loads the specified texture
042         */
043        protected void loadTexture(String par1Str)
044        {
045            RenderEngine var2 = this.renderManager.renderEngine;
046            var2.bindTexture(var2.getTexture(par1Str));
047        }
048    
049        /**
050         * loads the specified downloadable texture or alternative built in texture
051         */
052        protected boolean loadDownloadableImageTexture(String par1Str, String par2Str)
053        {
054            RenderEngine var3 = this.renderManager.renderEngine;
055            int var4 = var3.getTextureForDownloadableImage(par1Str, par2Str);
056    
057            if (var4 >= 0)
058            {
059                var3.bindTexture(var4);
060                return true;
061            }
062            else
063            {
064                return false;
065            }
066        }
067    
068        /**
069         * Renders fire on top of the entity. Args: entity, x, y, z, partialTickTime
070         */
071        private void renderEntityOnFire(Entity par1Entity, double par2, double par4, double par6, float par8)
072        {
073            GL11.glDisable(GL11.GL_LIGHTING);
074            int var9 = Block.fire.blockIndexInTexture;
075            int var10 = (var9 & 15) << 4;
076            int var11 = var9 & 240;
077            float var12 = (float)var10 / 256.0F;
078            float var13 = ((float)var10 + 15.99F) / 256.0F;
079            float var14 = (float)var11 / 256.0F;
080            float var15 = ((float)var11 + 15.99F) / 256.0F;
081            GL11.glPushMatrix();
082            GL11.glTranslatef((float)par2, (float)par4, (float)par6);
083            float var16 = par1Entity.width * 1.4F;
084            GL11.glScalef(var16, var16, var16);
085            this.loadTexture("/terrain.png");
086            Tessellator var17 = Tessellator.instance;
087            float var18 = 0.5F;
088            float var19 = 0.0F;
089            float var20 = par1Entity.height / var16;
090            float var21 = (float)(par1Entity.posY - par1Entity.boundingBox.minY);
091            GL11.glRotatef(-this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
092            GL11.glTranslatef(0.0F, 0.0F, -0.3F + (float)((int)var20) * 0.02F);
093            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
094            float var22 = 0.0F;
095            int var23 = 0;
096            var17.startDrawingQuads();
097    
098            while (var20 > 0.0F)
099            {
100                if (var23 % 2 == 0)
101                {
102                    var12 = (float)var10 / 256.0F;
103                    var13 = ((float)var10 + 15.99F) / 256.0F;
104                    var14 = (float)var11 / 256.0F;
105                    var15 = ((float)var11 + 15.99F) / 256.0F;
106                }
107                else
108                {
109                    var12 = (float)var10 / 256.0F;
110                    var13 = ((float)var10 + 15.99F) / 256.0F;
111                    var14 = (float)(var11 + 16) / 256.0F;
112                    var15 = ((float)(var11 + 16) + 15.99F) / 256.0F;
113                }
114    
115                if (var23 / 2 % 2 == 0)
116                {
117                    float var24 = var13;
118                    var13 = var12;
119                    var12 = var24;
120                }
121    
122                var17.addVertexWithUV((double)(var18 - var19), (double)(0.0F - var21), (double)var22, (double)var13, (double)var15);
123                var17.addVertexWithUV((double)(-var18 - var19), (double)(0.0F - var21), (double)var22, (double)var12, (double)var15);
124                var17.addVertexWithUV((double)(-var18 - var19), (double)(1.4F - var21), (double)var22, (double)var12, (double)var14);
125                var17.addVertexWithUV((double)(var18 - var19), (double)(1.4F - var21), (double)var22, (double)var13, (double)var14);
126                var20 -= 0.45F;
127                var21 -= 0.45F;
128                var18 *= 0.9F;
129                var22 += 0.03F;
130                ++var23;
131            }
132    
133            var17.draw();
134            GL11.glPopMatrix();
135            GL11.glEnable(GL11.GL_LIGHTING);
136        }
137    
138        /**
139         * Renders the entity shadows at the position, shadow alpha and partialTickTime. Args: entity, x, y, z, shadowAlpha,
140         * partialTickTime
141         */
142        private void renderShadow(Entity par1Entity, double par2, double par4, double par6, float par8, float par9)
143        {
144            GL11.glEnable(GL11.GL_BLEND);
145            GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
146            RenderEngine var10 = this.renderManager.renderEngine;
147            var10.bindTexture(var10.getTexture("%clamp%/misc/shadow.png"));
148            World var11 = this.getWorldFromRenderManager();
149            GL11.glDepthMask(false);
150            float var12 = this.shadowSize;
151    
152            if (par1Entity instanceof EntityLiving)
153            {
154                EntityLiving var13 = (EntityLiving)par1Entity;
155                var12 *= var13.getRenderSizeModifier();
156    
157                if (var13.isChild())
158                {
159                    var12 *= 0.5F;
160                }
161            }
162    
163            double var36 = par1Entity.lastTickPosX + (par1Entity.posX - par1Entity.lastTickPosX) * (double)par9;
164            double var15 = par1Entity.lastTickPosY + (par1Entity.posY - par1Entity.lastTickPosY) * (double)par9 + (double)par1Entity.getShadowSize();
165            double var17 = par1Entity.lastTickPosZ + (par1Entity.posZ - par1Entity.lastTickPosZ) * (double)par9;
166            int var19 = MathHelper.floor_double(var36 - (double)var12);
167            int var20 = MathHelper.floor_double(var36 + (double)var12);
168            int var21 = MathHelper.floor_double(var15 - (double)var12);
169            int var22 = MathHelper.floor_double(var15);
170            int var23 = MathHelper.floor_double(var17 - (double)var12);
171            int var24 = MathHelper.floor_double(var17 + (double)var12);
172            double var25 = par2 - var36;
173            double var27 = par4 - var15;
174            double var29 = par6 - var17;
175            Tessellator var31 = Tessellator.instance;
176            var31.startDrawingQuads();
177    
178            for (int var32 = var19; var32 <= var20; ++var32)
179            {
180                for (int var33 = var21; var33 <= var22; ++var33)
181                {
182                    for (int var34 = var23; var34 <= var24; ++var34)
183                    {
184                        int var35 = var11.getBlockId(var32, var33 - 1, var34);
185    
186                        if (var35 > 0 && var11.getBlockLightValue(var32, var33, var34) > 3)
187                        {
188                            this.renderShadowOnBlock(Block.blocksList[var35], par2, par4 + (double)par1Entity.getShadowSize(), par6, var32, var33, var34, par8, var12, var25, var27 + (double)par1Entity.getShadowSize(), var29);
189                        }
190                    }
191                }
192            }
193    
194            var31.draw();
195            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
196            GL11.glDisable(GL11.GL_BLEND);
197            GL11.glDepthMask(true);
198        }
199    
200        /**
201         * Returns the render manager's world object
202         */
203        private World getWorldFromRenderManager()
204        {
205            return this.renderManager.worldObj;
206        }
207    
208        /**
209         * Renders a shadow projected down onto the specified block. Brightness of the block plus how far away on the Y axis
210         * determines the alpha of the shadow.  Args: block, centerX, centerY, centerZ, blockX, blockY, blockZ, baseAlpha,
211         * shadowSize, xOffset, yOffset, zOffset
212         */
213        private void renderShadowOnBlock(Block par1Block, double par2, double par4, double par6, int par8, int par9, int par10, float par11, float par12, double par13, double par15, double par17)
214        {
215            Tessellator var19 = Tessellator.instance;
216    
217            if (par1Block.renderAsNormalBlock())
218            {
219                double var20 = ((double)par11 - (par4 - ((double)par9 + par15)) / 2.0D) * 0.5D * (double)this.getWorldFromRenderManager().getLightBrightness(par8, par9, par10);
220    
221                if (var20 >= 0.0D)
222                {
223                    if (var20 > 1.0D)
224                    {
225                        var20 = 1.0D;
226                    }
227    
228                    var19.setColorRGBA_F(1.0F, 1.0F, 1.0F, (float)var20);
229                    double var22 = (double)par8 + par1Block.getBlockBoundsMinX() + par13;
230                    double var24 = (double)par8 + par1Block.getBlockBoundsMaxX() + par13;
231                    double var26 = (double)par9 + par1Block.getBlockBoundsMinY() + par15 + 0.015625D;
232                    double var28 = (double)par10 + par1Block.getBlockBoundsMinZ() + par17;
233                    double var30 = (double)par10 + par1Block.getBlockBoundsMaxZ() + par17;
234                    float var32 = (float)((par2 - var22) / 2.0D / (double)par12 + 0.5D);
235                    float var33 = (float)((par2 - var24) / 2.0D / (double)par12 + 0.5D);
236                    float var34 = (float)((par6 - var28) / 2.0D / (double)par12 + 0.5D);
237                    float var35 = (float)((par6 - var30) / 2.0D / (double)par12 + 0.5D);
238                    var19.addVertexWithUV(var22, var26, var28, (double)var32, (double)var34);
239                    var19.addVertexWithUV(var22, var26, var30, (double)var32, (double)var35);
240                    var19.addVertexWithUV(var24, var26, var30, (double)var33, (double)var35);
241                    var19.addVertexWithUV(var24, var26, var28, (double)var33, (double)var34);
242                }
243            }
244        }
245    
246        /**
247         * Renders a white box with the bounds of the AABB translated by the offset. Args: aabb, x, y, z
248         */
249        public static void renderOffsetAABB(AxisAlignedBB par0AxisAlignedBB, double par1, double par3, double par5)
250        {
251            GL11.glDisable(GL11.GL_TEXTURE_2D);
252            Tessellator var7 = Tessellator.instance;
253            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
254            var7.startDrawingQuads();
255            var7.setTranslation(par1, par3, par5);
256            var7.setNormal(0.0F, 0.0F, -1.0F);
257            var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ);
258            var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ);
259            var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ);
260            var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ);
261            var7.setNormal(0.0F, 0.0F, 1.0F);
262            var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ);
263            var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ);
264            var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ);
265            var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ);
266            var7.setNormal(0.0F, -1.0F, 0.0F);
267            var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ);
268            var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ);
269            var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ);
270            var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ);
271            var7.setNormal(0.0F, 1.0F, 0.0F);
272            var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ);
273            var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ);
274            var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ);
275            var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ);
276            var7.setNormal(-1.0F, 0.0F, 0.0F);
277            var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ);
278            var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ);
279            var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ);
280            var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ);
281            var7.setNormal(1.0F, 0.0F, 0.0F);
282            var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ);
283            var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ);
284            var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ);
285            var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ);
286            var7.setTranslation(0.0D, 0.0D, 0.0D);
287            var7.draw();
288            GL11.glEnable(GL11.GL_TEXTURE_2D);
289        }
290    
291        /**
292         * Adds to the tesselator a box using the aabb for the bounds. Args: aabb
293         */
294        public static void renderAABB(AxisAlignedBB par0AxisAlignedBB)
295        {
296            Tessellator var1 = Tessellator.instance;
297            var1.startDrawingQuads();
298            var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ);
299            var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ);
300            var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ);
301            var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ);
302            var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ);
303            var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ);
304            var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ);
305            var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ);
306            var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ);
307            var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ);
308            var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ);
309            var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ);
310            var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ);
311            var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ);
312            var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ);
313            var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ);
314            var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ);
315            var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ);
316            var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ);
317            var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ);
318            var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ);
319            var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ);
320            var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ);
321            var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ);
322            var1.draw();
323        }
324    
325        /**
326         * Sets the RenderManager.
327         */
328        public void setRenderManager(RenderManager par1RenderManager)
329        {
330            this.renderManager = par1RenderManager;
331        }
332    
333        /**
334         * Renders the entity's shadow and fire (if its on fire). Args: entity, x, y, z, yaw, partialTickTime
335         */
336        public void doRenderShadowAndFire(Entity par1Entity, double par2, double par4, double par6, float par8, float par9)
337        {
338            if (this.renderManager.options.fancyGraphics && this.shadowSize > 0.0F && !par1Entity.getHasActivePotion())
339            {
340                double var10 = this.renderManager.getDistanceToCamera(par1Entity.posX, par1Entity.posY, par1Entity.posZ);
341                float var12 = (float)((1.0D - var10 / 256.0D) * (double)this.shadowOpaque);
342    
343                if (var12 > 0.0F)
344                {
345                    this.renderShadow(par1Entity, par2, par4, par6, var12, par9);
346                }
347            }
348    
349            if (par1Entity.canRenderOnFire())
350            {
351                this.renderEntityOnFire(par1Entity, par2, par4, par6, par9);
352            }
353        }
354    
355        /**
356         * Returns the font renderer from the set render manager
357         */
358        public FontRenderer getFontRendererFromRenderManager()
359        {
360            return this.renderManager.getFontRenderer();
361        }
362    }