    001package net.minecraft.client.renderer.entity;
    002
    003import cpw.mods.fml.relauncher.Side;
    004import cpw.mods.fml.relauncher.SideOnly;
    005import java.util.HashMap;
    006import java.util.Iterator;
    007import java.util.Map;
    008import net.minecraft.block.Block;
    009import net.minecraft.client.entity.render.RenderMinecartMobSpawner;
    010import net.minecraft.client.gui.FontRenderer;
    011import net.minecraft.client.model.ModelBiped;
    012import net.minecraft.client.model.ModelChicken;
    013import net.minecraft.client.model.ModelCow;
    014import net.minecraft.client.model.ModelOcelot;
    015import net.minecraft.client.model.ModelPig;
    016import net.minecraft.client.model.ModelSheep1;
    017import net.minecraft.client.model.ModelSheep2;
    018import net.minecraft.client.model.ModelSlime;
    019import net.minecraft.client.model.ModelSquid;
    020import net.minecraft.client.model.ModelWolf;
    021import net.minecraft.client.model.ModelZombie;
    022import net.minecraft.client.renderer.ItemRenderer;
    023import net.minecraft.client.renderer.OpenGlHelper;
    024import net.minecraft.client.renderer.RenderEngine;
    025import net.minecraft.client.renderer.Tessellator;
    026import net.minecraft.client.renderer.texture.IconRegister;
    027import net.minecraft.client.renderer.tileentity.RenderEnderCrystal;
    028import net.minecraft.client.renderer.tileentity.RenderItemFrame;
    029import net.minecraft.client.renderer.tileentity.RenderWitherSkull;
    030import net.minecraft.client.settings.GameSettings;
    031import net.minecraft.crash.CrashReport;
    032import net.minecraft.crash.CrashReportCategory;
    033import net.minecraft.entity.Entity;
    034import net.minecraft.entity.EntityLiving;
    035import net.minecraft.entity.ai.EntityMinecartMobSpawner;
    036import net.minecraft.entity.boss.EntityDragon;
    037import net.minecraft.entity.boss.EntityWither;
    038import net.minecraft.entity.effect.EntityLightningBolt;
    039import net.minecraft.entity.item.EntityBoat;
    040import net.minecraft.entity.item.EntityEnderCrystal;
    041import net.minecraft.entity.item.EntityEnderEye;
    042import net.minecraft.entity.item.EntityEnderPearl;
    043import net.minecraft.entity.item.EntityExpBottle;
    044import net.minecraft.entity.item.EntityFallingSand;
    045import net.minecraft.entity.item.EntityFireworkRocket;
    046import net.minecraft.entity.item.EntityItem;
    047import net.minecraft.entity.item.EntityItemFrame;
    048import net.minecraft.entity.item.EntityMinecart;
    049import net.minecraft.entity.item.EntityMinecartTNT;
    050import net.minecraft.entity.item.EntityPainting;
    051import net.minecraft.entity.item.EntityTNTPrimed;
    052import net.minecraft.entity.item.EntityXPOrb;
    053import net.minecraft.entity.monster.EntityBlaze;
    054import net.minecraft.entity.monster.EntityCaveSpider;
    055import net.minecraft.entity.monster.EntityCreeper;
    056import net.minecraft.entity.monster.EntityEnderman;
    057import net.minecraft.entity.monster.EntityGhast;
    058import net.minecraft.entity.monster.EntityGiantZombie;
    059import net.minecraft.entity.monster.EntityIronGolem;
    060import net.minecraft.entity.monster.EntityMagmaCube;
    061import net.minecraft.entity.monster.EntitySilverfish;
    062import net.minecraft.entity.monster.EntitySkeleton;
    063import net.minecraft.entity.monster.EntitySlime;
    064import net.minecraft.entity.monster.EntitySnowman;
    065import net.minecraft.entity.monster.EntitySpider;
    066import net.minecraft.entity.monster.EntityWitch;
    067import net.minecraft.entity.monster.EntityZombie;
    068import net.minecraft.entity.passive.EntityBat;
    069import net.minecraft.entity.passive.EntityChicken;
    070import net.minecraft.entity.passive.EntityCow;
    071import net.minecraft.entity.passive.EntityMooshroom;
    072import net.minecraft.entity.passive.EntityOcelot;
    073import net.minecraft.entity.passive.EntityPig;
    074import net.minecraft.entity.passive.EntitySheep;
    075import net.minecraft.entity.passive.EntitySquid;
    076import net.minecraft.entity.passive.EntityVillager;
    077import net.minecraft.entity.passive.EntityWolf;
    078import net.minecraft.entity.player.EntityPlayer;
    079import net.minecraft.entity.projectile.EntityArrow;
    080import net.minecraft.entity.projectile.EntityEgg;
    081import net.minecraft.entity.projectile.EntityFishHook;
    082import net.minecraft.entity.projectile.EntityLargeFireball;
    083import net.minecraft.entity.projectile.EntityPotion;
    084import net.minecraft.entity.projectile.EntitySmallFireball;
    085import net.minecraft.entity.projectile.EntitySnowball;
    086import net.minecraft.entity.projectile.EntityWitherSkull;
    087import net.minecraft.item.Item;
    088import net.minecraft.util.MathHelper;
    089import net.minecraft.util.ReportedException;
    090import net.minecraft.world.World;
    091import org.lwjgl.opengl.GL11;
    092
    093@SideOnly(Side.CLIENT)
    094public class RenderManager
    095{
    096    /** A map of entity classes and the associated renderer. */
    097    public Map entityRenderMap = new HashMap();
    098
    099    /** The static instance of RenderManager. */
    100    public static RenderManager instance = new RenderManager();
    101
    102    /** Renders fonts */
    103    private FontRenderer fontRenderer;
    104    public static double renderPosX;
    105    public static double renderPosY;
    106    public static double renderPosZ;
    107    public RenderEngine renderEngine;
    108    public ItemRenderer itemRenderer;
    109
    110    /** Reference to the World object. */
    111    public World worldObj;
    112
    113    /** Rendermanager's variable for the player */
    114    public EntityLiving livingPlayer;
    115    public EntityLiving field_96451_i;
    116    public float playerViewY;
    117    public float playerViewX;
    118
    119    /** Reference to the GameSettings object. */
    120    public GameSettings options;
    121    public double viewerPosX;
    122    public double viewerPosY;
    123    public double viewerPosZ;
    124    public static boolean field_85095_o = false;
    125
    126    private RenderManager()
    127    {
    128        this.entityRenderMap.put(EntitySpider.class, new RenderSpider());
    129        this.entityRenderMap.put(EntityCaveSpider.class, new RenderSpider());
    130        this.entityRenderMap.put(EntityPig.class, new RenderPig(new ModelPig(), new ModelPig(0.5F), 0.7F));
    131        this.entityRenderMap.put(EntitySheep.class, new RenderSheep(new ModelSheep2(), new ModelSheep1(), 0.7F));
    132        this.entityRenderMap.put(EntityCow.class, new RenderCow(new ModelCow(), 0.7F));
    133        this.entityRenderMap.put(EntityMooshroom.class, new RenderMooshroom(new ModelCow(), 0.7F));
    134        this.entityRenderMap.put(EntityWolf.class, new RenderWolf(new ModelWolf(), new ModelWolf(), 0.5F));
    135        this.entityRenderMap.put(EntityChicken.class, new RenderChicken(new ModelChicken(), 0.3F));
    136        this.entityRenderMap.put(EntityOcelot.class, new RenderOcelot(new ModelOcelot(), 0.4F));
    137        this.entityRenderMap.put(EntitySilverfish.class, new RenderSilverfish());
    138        this.entityRenderMap.put(EntityCreeper.class, new RenderCreeper());
    139        this.entityRenderMap.put(EntityEnderman.class, new RenderEnderman());
    140        this.entityRenderMap.put(EntitySnowman.class, new RenderSnowMan());
    141        this.entityRenderMap.put(EntitySkeleton.class, new RenderSkeleton());
    142        this.entityRenderMap.put(EntityWitch.class, new RenderWitch());
    143        this.entityRenderMap.put(EntityBlaze.class, new RenderBlaze());
    144        this.entityRenderMap.put(EntityZombie.class, new RenderZombie());
    145        this.entityRenderMap.put(EntitySlime.class, new RenderSlime(new ModelSlime(16), new ModelSlime(0), 0.25F));
    146        this.entityRenderMap.put(EntityMagmaCube.class, new RenderMagmaCube());
    147        this.entityRenderMap.put(EntityPlayer.class, new RenderPlayer());
    148        this.entityRenderMap.put(EntityGiantZombie.class, new RenderGiantZombie(new ModelZombie(), 0.5F, 6.0F));
    149        this.entityRenderMap.put(EntityGhast.class, new RenderGhast());
    150        this.entityRenderMap.put(EntitySquid.class, new RenderSquid(new ModelSquid(), 0.7F));
    151        this.entityRenderMap.put(EntityVillager.class, new RenderVillager());
    152        this.entityRenderMap.put(EntityIronGolem.class, new RenderIronGolem());
    153        this.entityRenderMap.put(EntityLiving.class, new RenderLiving(new ModelBiped(), 0.5F));
    154        this.entityRenderMap.put(EntityBat.class, new RenderBat());
    155        this.entityRenderMap.put(EntityDragon.class, new RenderDragon());
    156        this.entityRenderMap.put(EntityEnderCrystal.class, new RenderEnderCrystal());
    157        this.entityRenderMap.put(EntityWither.class, new RenderWither());
    158        this.entityRenderMap.put(Entity.class, new RenderEntity());
    159        this.entityRenderMap.put(EntityPainting.class, new RenderPainting());
    160        this.entityRenderMap.put(EntityItemFrame.class, new RenderItemFrame());
    161        this.entityRenderMap.put(EntityArrow.class, new RenderArrow());
    162        this.entityRenderMap.put(EntitySnowball.class, new RenderSnowball(Item.snowball));
    163        this.entityRenderMap.put(EntityEnderPearl.class, new RenderSnowball(Item.enderPearl));
    164        this.entityRenderMap.put(EntityEnderEye.class, new RenderSnowball(Item.eyeOfEnder));
    165        this.entityRenderMap.put(EntityEgg.class, new RenderSnowball(Item.egg));
    166        this.entityRenderMap.put(EntityPotion.class, new RenderSnowball(Item.potion, 16384));
    167        this.entityRenderMap.put(EntityExpBottle.class, new RenderSnowball(Item.expBottle));
    168        this.entityRenderMap.put(EntityFireworkRocket.class, new RenderSnowball(Item.firework));
    169        this.entityRenderMap.put(EntityLargeFireball.class, new RenderFireball(2.0F));
    170        this.entityRenderMap.put(EntitySmallFireball.class, new RenderFireball(0.5F));
    171        this.entityRenderMap.put(EntityWitherSkull.class, new RenderWitherSkull());
    172        this.entityRenderMap.put(EntityItem.class, new RenderItem());
    173        this.entityRenderMap.put(EntityXPOrb.class, new RenderXPOrb());
    174        this.entityRenderMap.put(EntityTNTPrimed.class, new RenderTNTPrimed());
    175        this.entityRenderMap.put(EntityFallingSand.class, new RenderFallingSand());
    176        this.entityRenderMap.put(EntityMinecartTNT.class, new RenderTntMinecart());
    177        this.entityRenderMap.put(EntityMinecartMobSpawner.class, new RenderMinecartMobSpawner());
    178        this.entityRenderMap.put(EntityMinecart.class, new RenderMinecart());
    179        this.entityRenderMap.put(EntityBoat.class, new RenderBoat());
    180        this.entityRenderMap.put(EntityFishHook.class, new RenderFish());
    181        this.entityRenderMap.put(EntityLightningBolt.class, new RenderLightningBolt());
    182        Iterator iterator = this.entityRenderMap.values().iterator();
    183
    184        while (iterator.hasNext())
    185        {
    186            Render render = (Render)iterator.next();
    187            render.setRenderManager(this);
    188        }
    189    }
    190
    191    public Render getEntityClassRenderObject(Class par1Class)
    192    {
    193        Render render = (Render)this.entityRenderMap.get(par1Class);
    194
    195        if (render == null && par1Class != Entity.class)
    196        {
    197            render = this.getEntityClassRenderObject(par1Class.getSuperclass());
    198            this.entityRenderMap.put(par1Class, render);
    199        }
    200
    201        return render;
    202    }
    203
    204    public Render getEntityRenderObject(Entity par1Entity)
    205    {
    206        return this.getEntityClassRenderObject(par1Entity.getClass());
    207    }
    208
    209    /**
    210     * Caches the current frame's active render info, including the current World, RenderEngine, GameSettings and
    211     * FontRenderer settings, as well as interpolated player position, pitch and yaw.
    212     */
    213    public void cacheActiveRenderInfo(World par1World, RenderEngine par2RenderEngine, FontRenderer par3FontRenderer, EntityLiving par4EntityLiving, EntityLiving par5EntityLiving, GameSettings par6GameSettings, float par7)
    214    {
    215        this.worldObj = par1World;
    216        this.renderEngine = par2RenderEngine;
    217        this.options = par6GameSettings;
    218        this.livingPlayer = par4EntityLiving;
    219        this.field_96451_i = par5EntityLiving;
    220        this.fontRenderer = par3FontRenderer;
    221
    222        if (par4EntityLiving.isPlayerSleeping())
    223        {
    224            int x = MathHelper.floor_double(par4EntityLiving.posX);
    225            int y = MathHelper.floor_double(par4EntityLiving.posY);
    226            int z = MathHelper.floor_double(par4EntityLiving.posZ);
    227            Block block = Block.blocksList[par1World.getBlockId(x, y, z)];
    228
    229            if (block != null && block.isBed(par1World, x, y, z, par4EntityLiving))
    230            {
    231                int k = block.getBedDirection(par1World, x, y, z);;
    232                this.playerViewY = (float)(k * 90 + 180);
    233                this.playerViewX = 0.0F;
    234            }
    235        }
    236        else
    237        {
    238            this.playerViewY = par4EntityLiving.prevRotationYaw + (par4EntityLiving.rotationYaw - par4EntityLiving.prevRotationYaw) * par7;
    239            this.playerViewX = par4EntityLiving.prevRotationPitch + (par4EntityLiving.rotationPitch - par4EntityLiving.prevRotationPitch) * par7;
    240        }
    241
    242        if (par6GameSettings.thirdPersonView == 2)
    243        {
    244            this.playerViewY += 180.0F;
    245        }
    246
    247        this.viewerPosX = par4EntityLiving.lastTickPosX + (par4EntityLiving.posX - par4EntityLiving.lastTickPosX) * (double)par7;
    248        this.viewerPosY = par4EntityLiving.lastTickPosY + (par4EntityLiving.posY - par4EntityLiving.lastTickPosY) * (double)par7;
    249        this.viewerPosZ = par4EntityLiving.lastTickPosZ + (par4EntityLiving.posZ - par4EntityLiving.lastTickPosZ) * (double)par7;
    250    }
    251
    252    /**
    253     * Will render the specified entity at the specified partial tick time. Args: entity, partialTickTime
    254     */
    255    public void renderEntity(Entity par1Entity, float par2)
    256    {
    257        if (par1Entity.ticksExisted == 0)
    258        {
    259            par1Entity.lastTickPosX = par1Entity.posX;
    260            par1Entity.lastTickPosY = par1Entity.posY;
    261            par1Entity.lastTickPosZ = par1Entity.posZ;
    262        }
    263
    264        double d0 = par1Entity.lastTickPosX + (par1Entity.posX - par1Entity.lastTickPosX) * (double)par2;
    265        double d1 = par1Entity.lastTickPosY + (par1Entity.posY - par1Entity.lastTickPosY) * (double)par2;
    266        double d2 = par1Entity.lastTickPosZ + (par1Entity.posZ - par1Entity.lastTickPosZ) * (double)par2;
    267        float f1 = par1Entity.prevRotationYaw + (par1Entity.rotationYaw - par1Entity.prevRotationYaw) * par2;
    268        int i = par1Entity.getBrightnessForRender(par2);
    269
    270        if (par1Entity.isBurning())
    271        {
    272            i = 15728880;
    273        }
    274
    275        int j = i % 65536;
    276        int k = i / 65536;
    277        OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)j / 1.0F, (float)k / 1.0F);
    278        GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    279        this.renderEntityWithPosYaw(par1Entity, d0 - renderPosX, d1 - renderPosY, d2 - renderPosZ, f1, par2);
    280    }
    281
    282    /**
    283     * Renders the specified entity with the passed in position, yaw, and partialTickTime. Args: entity, x, y, z, yaw,
    284     * partialTickTime
    285     */
    286    public void renderEntityWithPosYaw(Entity par1Entity, double par2, double par4, double par6, float par8, float par9)
    287    {
    288        Render render = null;
    289
    290        try
    291        {
    292            render = this.getEntityRenderObject(par1Entity);
    293
    294            if (render != null && this.renderEngine != null)
    295            {
    296                if (field_85095_o && !par1Entity.getHasActivePotion())
    297                {
    298                    try
    299                    {
    300                        this.func_85094_b(par1Entity, par2, par4, par6, par8, par9);
    301                    }
    302                    catch (Throwable throwable)
    303                    {
    304                        throw new ReportedException(CrashReport.makeCrashReport(throwable, "Rendering entity hitbox in world"));
    305                    }
    306                }
    307
    308                try
    309                {
    310                    render.doRender(par1Entity, par2, par4, par6, par8, par9);
    311                }
    312                catch (Throwable throwable1)
    313                {
    314                    throw new ReportedException(CrashReport.makeCrashReport(throwable1, "Rendering entity in world"));
    315                }
    316
    317                try
    318                {
    319                    render.doRenderShadowAndFire(par1Entity, par2, par4, par6, par8, par9);
    320                }
    321                catch (Throwable throwable2)
    322                {
    323                    throw new ReportedException(CrashReport.makeCrashReport(throwable2, "Post-rendering entity in world"));
    324                }
    325            }
    326        }
    327        catch (Throwable throwable3)
    328        {
    329            CrashReport crashreport = CrashReport.makeCrashReport(throwable3, "Rendering entity in world");
    330            CrashReportCategory crashreportcategory = crashreport.makeCategory("Entity being rendered");
    331            par1Entity.func_85029_a(crashreportcategory);
    332            CrashReportCategory crashreportcategory1 = crashreport.makeCategory("Renderer details");
    333            crashreportcategory1.addCrashSection("Assigned renderer", render);
    334            crashreportcategory1.addCrashSection("Location", CrashReportCategory.func_85074_a(par2, par4, par6));
    335            crashreportcategory1.addCrashSection("Rotation", Float.valueOf(par8));
    336            crashreportcategory1.addCrashSection("Delta", Float.valueOf(par9));
    337            throw new ReportedException(crashreport);
    338        }
    339    }
    340
    341    private void func_85094_b(Entity par1Entity, double par2, double par4, double par6, float par8, float par9)
    342    {
    343        GL11.glDepthMask(false);
    344        GL11.glDisable(GL11.GL_TEXTURE_2D);
    345        GL11.glDisable(GL11.GL_LIGHTING);
    346        GL11.glDisable(GL11.GL_CULL_FACE);
    347        GL11.glDisable(GL11.GL_BLEND);
    348        GL11.glPushMatrix();
    349        Tessellator tessellator = Tessellator.instance;
    350        tessellator.startDrawingQuads();
    351        tessellator.setColorRGBA(255, 255, 255, 32);
    352        double d3 = (double)(-par1Entity.width / 2.0F);
    353        double d4 = (double)(-par1Entity.width / 2.0F);
    354        double d5 = (double)(par1Entity.width / 2.0F);
    355        double d6 = (double)(-par1Entity.width / 2.0F);
    356        double d7 = (double)(-par1Entity.width / 2.0F);
    357        double d8 = (double)(par1Entity.width / 2.0F);
    358        double d9 = (double)(par1Entity.width / 2.0F);
    359        double d10 = (double)(par1Entity.width / 2.0F);
    360        double d11 = (double)par1Entity.height;
    361        tessellator.addVertex(par2 + d3, par4 + d11, par6 + d4);
    362        tessellator.addVertex(par2 + d3, par4, par6 + d4);
    363        tessellator.addVertex(par2 + d5, par4, par6 + d6);
    364        tessellator.addVertex(par2 + d5, par4 + d11, par6 + d6);
    365        tessellator.addVertex(par2 + d9, par4 + d11, par6 + d10);
    366        tessellator.addVertex(par2 + d9, par4, par6 + d10);
    367        tessellator.addVertex(par2 + d7, par4, par6 + d8);
    368        tessellator.addVertex(par2 + d7, par4 + d11, par6 + d8);
    369        tessellator.addVertex(par2 + d5, par4 + d11, par6 + d6);
    370        tessellator.addVertex(par2 + d5, par4, par6 + d6);
    371        tessellator.addVertex(par2 + d9, par4, par6 + d10);
    372        tessellator.addVertex(par2 + d9, par4 + d11, par6 + d10);
    373        tessellator.addVertex(par2 + d7, par4 + d11, par6 + d8);
    374        tessellator.addVertex(par2 + d7, par4, par6 + d8);
    375        tessellator.addVertex(par2 + d3, par4, par6 + d4);
    376        tessellator.addVertex(par2 + d3, par4 + d11, par6 + d4);
    377        tessellator.draw();
    378        GL11.glPopMatrix();
    379        GL11.glEnable(GL11.GL_TEXTURE_2D);
    380        GL11.glEnable(GL11.GL_LIGHTING);
    381        GL11.glEnable(GL11.GL_CULL_FACE);
    382        GL11.glDisable(GL11.GL_BLEND);
    383        GL11.glDepthMask(true);
    384    }
    385
    386    /**
    387     * World sets this RenderManager's worldObj to the world provided
    388     */
    389    public void set(World par1World)
    390    {
    391        this.worldObj = par1World;
    392    }
    393
    394    public double getDistanceToCamera(double par1, double par3, double par5)
    395    {
    396        double d3 = par1 - this.viewerPosX;
    397        double d4 = par3 - this.viewerPosY;
    398        double d5 = par5 - this.viewerPosZ;
    399        return d3 * d3 + d4 * d4 + d5 * d5;
    400    }
    401
    402    /**
    403     * Returns the font renderer
    404     */
    405    public FontRenderer getFontRenderer()
    406    {
    407        return this.fontRenderer;
    408    }
    409
    410    public void updateIcons(IconRegister par1IconRegister)
    411    {
    412        Iterator iterator = this.entityRenderMap.values().iterator();
    413
    414        while (iterator.hasNext())
    415        {
    416            Render render = (Render)iterator.next();
    417            render.updateIcons(par1IconRegister);
    418        }
    419    }
    420}