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.func_82115_m())
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}