    001package net.minecraft.client.renderer.tileentity;
    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.client.gui.FontRenderer;
    009import net.minecraft.client.renderer.OpenGlHelper;
    010import net.minecraft.client.renderer.RenderEngine;
    011import net.minecraft.client.renderer.entity.RenderEnchantmentTable;
    012import net.minecraft.crash.CrashReport;
    013import net.minecraft.crash.CrashReportCategory;
    014import net.minecraft.entity.EntityLiving;
    015import net.minecraft.tileentity.TileEntity;
    016import net.minecraft.tileentity.TileEntityBeacon;
    017import net.minecraft.tileentity.TileEntityChest;
    018import net.minecraft.tileentity.TileEntityEnchantmentTable;
    019import net.minecraft.tileentity.TileEntityEndPortal;
    020import net.minecraft.tileentity.TileEntityEnderChest;
    021import net.minecraft.tileentity.TileEntityMobSpawner;
    022import net.minecraft.tileentity.TileEntityPiston;
    023import net.minecraft.tileentity.TileEntitySign;
    024import net.minecraft.tileentity.TileEntitySkull;
    025import net.minecraft.util.ReportedException;
    026import net.minecraft.world.World;
    027import org.lwjgl.opengl.GL11;
    028
    029@SideOnly(Side.CLIENT)
    030public class TileEntityRenderer
    031{
    032    /**
    033     * A mapping of TileEntitySpecialRenderers used for each TileEntity that has one
    034     */
    035    public Map specialRendererMap = new HashMap();
    036
    037    /** The static instance of TileEntityRenderer */
    038    public static TileEntityRenderer instance = new TileEntityRenderer();
    039
    040    /** The FontRenderer instance used by the TileEntityRenderer */
    041    private FontRenderer fontRenderer;
    042
    043    /** The player's current X position (same as playerX) */
    044    public static double staticPlayerX;
    045
    046    /** The player's current Y position (same as playerY) */
    047    public static double staticPlayerY;
    048
    049    /** The player's current Z position (same as playerZ) */
    050    public static double staticPlayerZ;
    051
    052    /** The RenderEngine instance used by the TileEntityRenderer */
    053    public RenderEngine renderEngine;
    054
    055    /** Reference to the World object. */
    056    public World worldObj;
    057    public EntityLiving entityLivingPlayer;
    058    public float playerYaw;
    059    public float playerPitch;
    060
    061    /** The player's X position in this rendering context */
    062    public double playerX;
    063
    064    /** The player's Y position in this rendering context */
    065    public double playerY;
    066
    067    /** The player's Z position in this rendering context */
    068    public double playerZ;
    069
    070    private TileEntityRenderer()
    071    {
    072        this.specialRendererMap.put(TileEntitySign.class, new TileEntitySignRenderer());
    073        this.specialRendererMap.put(TileEntityMobSpawner.class, new TileEntityMobSpawnerRenderer());
    074        this.specialRendererMap.put(TileEntityPiston.class, new TileEntityRendererPiston());
    075        this.specialRendererMap.put(TileEntityChest.class, new TileEntityChestRenderer());
    076        this.specialRendererMap.put(TileEntityEnderChest.class, new TileEntityEnderChestRenderer());
    077        this.specialRendererMap.put(TileEntityEnchantmentTable.class, new RenderEnchantmentTable());
    078        this.specialRendererMap.put(TileEntityEndPortal.class, new RenderEndPortal());
    079        this.specialRendererMap.put(TileEntityBeacon.class, new TileEntityBeaconRenderer());
    080        this.specialRendererMap.put(TileEntitySkull.class, new TileEntitySkullRenderer());
    081        Iterator iterator = this.specialRendererMap.values().iterator();
    082
    083        while (iterator.hasNext())
    084        {
    085            TileEntitySpecialRenderer tileentityspecialrenderer = (TileEntitySpecialRenderer)iterator.next();
    086            tileentityspecialrenderer.setTileEntityRenderer(this);
    087        }
    088    }
    089
    090    /**
    091     * Returns the TileEntitySpecialRenderer used to render this TileEntity class, or null if it has no special renderer
    092     */
    093    public TileEntitySpecialRenderer getSpecialRendererForClass(Class par1Class)
    094    {
    095        TileEntitySpecialRenderer tileentityspecialrenderer = (TileEntitySpecialRenderer)this.specialRendererMap.get(par1Class);
    096
    097        if (tileentityspecialrenderer == null && par1Class != TileEntity.class)
    098        {
    099            tileentityspecialrenderer = this.getSpecialRendererForClass(par1Class.getSuperclass());
    100            this.specialRendererMap.put(par1Class, tileentityspecialrenderer);
    101        }
    102
    103        return tileentityspecialrenderer;
    104    }
    105
    106    /**
    107     * Returns true if this TileEntity instance has a TileEntitySpecialRenderer associated with it, false otherwise.
    108     */
    109    public boolean hasSpecialRenderer(TileEntity par1TileEntity)
    110    {
    111        return this.getSpecialRendererForEntity(par1TileEntity) != null;
    112    }
    113
    114    /**
    115     * Returns the TileEntitySpecialRenderer used to render this TileEntity instance, or null if it has no special
    116     * renderer
    117     */
    118    public TileEntitySpecialRenderer getSpecialRendererForEntity(TileEntity par1TileEntity)
    119    {
    120        return par1TileEntity == null ? null : this.getSpecialRendererForClass(par1TileEntity.getClass());
    121    }
    122
    123    /**
    124     * Caches several render-related references, including the active World, RenderEngine, FontRenderer, and the camera-
    125     * bound EntityLiving's interpolated pitch, yaw and position. Args: world, renderengine, fontrenderer, entityliving,
    126     * partialTickTime
    127     */
    128    public void cacheActiveRenderInfo(World par1World, RenderEngine par2RenderEngine, FontRenderer par3FontRenderer, EntityLiving par4EntityLiving, float par5)
    129    {
    130        if (this.worldObj != par1World)
    131        {
    132            this.setWorld(par1World);
    133        }
    134
    135        this.renderEngine = par2RenderEngine;
    136        this.entityLivingPlayer = par4EntityLiving;
    137        this.fontRenderer = par3FontRenderer;
    138        this.playerYaw = par4EntityLiving.prevRotationYaw + (par4EntityLiving.rotationYaw - par4EntityLiving.prevRotationYaw) * par5;
    139        this.playerPitch = par4EntityLiving.prevRotationPitch + (par4EntityLiving.rotationPitch - par4EntityLiving.prevRotationPitch) * par5;
    140        this.playerX = par4EntityLiving.lastTickPosX + (par4EntityLiving.posX - par4EntityLiving.lastTickPosX) * (double)par5;
    141        this.playerY = par4EntityLiving.lastTickPosY + (par4EntityLiving.posY - par4EntityLiving.lastTickPosY) * (double)par5;
    142        this.playerZ = par4EntityLiving.lastTickPosZ + (par4EntityLiving.posZ - par4EntityLiving.lastTickPosZ) * (double)par5;
    143    }
    144
    145    /**
    146     * Render this TileEntity at its current position from the player
    147     */
    148    public void renderTileEntity(TileEntity par1TileEntity, float par2)
    149    {
    150        if (par1TileEntity.getDistanceFrom(this.playerX, this.playerY, this.playerZ) < par1TileEntity.getMaxRenderDistanceSquared())
    151        {
    152            int i = this.worldObj.getLightBrightnessForSkyBlocks(par1TileEntity.xCoord, par1TileEntity.yCoord, par1TileEntity.zCoord, 0);
    153            int j = i % 65536;
    154            int k = i / 65536;
    155            OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)j / 1.0F, (float)k / 1.0F);
    156            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    157            this.renderTileEntityAt(par1TileEntity, (double)par1TileEntity.xCoord - staticPlayerX, (double)par1TileEntity.yCoord - staticPlayerY, (double)par1TileEntity.zCoord - staticPlayerZ, par2);
    158        }
    159    }
    160
    161    /**
    162     * Render this TileEntity at a given set of coordinates
    163     */
    164    public void renderTileEntityAt(TileEntity par1TileEntity, double par2, double par4, double par6, float par8)
    165    {
    166        TileEntitySpecialRenderer tileentityspecialrenderer = this.getSpecialRendererForEntity(par1TileEntity);
    167
    168        if (tileentityspecialrenderer != null)
    169        {
    170            try
    171            {
    172                tileentityspecialrenderer.renderTileEntityAt(par1TileEntity, par2, par4, par6, par8);
    173            }
    174            catch (Throwable throwable)
    175            {
    176                CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Rendering Tile Entity");
    177                CrashReportCategory crashreportcategory = crashreport.makeCategory("Tile Entity Details");
    178                par1TileEntity.func_85027_a(crashreportcategory);
    179                throw new ReportedException(crashreport);
    180            }
    181        }
    182    }
    183
    184    /**
    185     * Sets the world used by all TileEntitySpecialRender instances and notifies them of this change.
    186     */
    187    public void setWorld(World par1World)
    188    {
    189        this.worldObj = par1World;
    190        Iterator iterator = this.specialRendererMap.values().iterator();
    191
    192        while (iterator.hasNext())
    193        {
    194            TileEntitySpecialRenderer tileentityspecialrenderer = (TileEntitySpecialRenderer)iterator.next();
    195
    196            if (tileentityspecialrenderer != null)
    197            {
    198                tileentityspecialrenderer.onWorldChange(par1World);
    199            }
    200        }
    201    }
    202
    203    public FontRenderer getFontRenderer()
    204    {
    205        return this.fontRenderer;
    206    }
    207}