    001package net.minecraft.client.renderer.entity;
    002
    003import cpw.mods.fml.relauncher.Side;
    004import cpw.mods.fml.relauncher.SideOnly;
    005import net.minecraft.block.Block;
    006import net.minecraft.client.gui.FontRenderer;
    007import net.minecraft.client.model.ModelBase;
    008import net.minecraft.client.model.ModelBiped;
    009import net.minecraft.client.renderer.RenderBlocks;
    010import net.minecraft.client.renderer.RenderEngine;
    011import net.minecraft.client.renderer.Tessellator;
    012import net.minecraft.entity.Entity;
    013import net.minecraft.entity.EntityLiving;
    014import net.minecraft.util.AxisAlignedBB;
    015import net.minecraft.util.MathHelper;
    016import net.minecraft.world.World;
    017import org.lwjgl.opengl.GL11;
    018
    019@SideOnly(Side.CLIENT)
    020public 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}