001package net.minecraft.client.renderer.texture; 002 003import cpw.mods.fml.relauncher.Side; 004import cpw.mods.fml.relauncher.SideOnly; 005 006import java.awt.image.BufferedImage; 007import java.io.BufferedReader; 008import java.util.ArrayList; 009import java.util.List; 010 011import net.minecraft.client.texturepacks.ITexturePack; 012import net.minecraft.util.Icon; 013import net.minecraft.util.Tuple; 014 015@SideOnly(Side.CLIENT) 016public class TextureStitched implements Icon 017{ 018 private final String textureName; 019 020 /** texture sheet containing this texture */ 021 protected Texture textureSheet; 022 protected List textureList; 023 private List listAnimationTuples; 024 protected boolean rotated; 025 026 /** x position of this icon on the texture sheet in pixels */ 027 protected int originX; 028 029 /** y position of this icon on the texture sheet in pixels */ 030 protected int originY; 031 032 /** width of this icon in pixels */ 033 private int width; 034 035 /** height of this icon in pixels */ 036 private int height; 037 private float minU; 038 private float maxU; 039 private float minV; 040 private float maxV; 041 private float widthNorm; 042 private float heightNorm; 043 protected int frameCounter = 0; 044 protected int tickCounter = 0; 045 046 public static TextureStitched makeTextureStitched(String par0Str) 047 { 048 return (TextureStitched)("clock".equals(par0Str) ? new TextureClock() : ("compass".equals(par0Str) ? new TextureCompass() : new TextureStitched(par0Str))); 049 } 050 051 protected TextureStitched(String par1) 052 { 053 this.textureName = par1; 054 } 055 056 public void init(Texture par1Texture, List par2List, int par3, int par4, int par5, int par6, boolean par7) 057 { 058 this.textureSheet = par1Texture; 059 this.textureList = par2List; 060 this.originX = par3; 061 this.originY = par4; 062 this.width = par5; 063 this.height = par6; 064 this.rotated = par7; 065 float f = 0.01F / (float)par1Texture.getWidth(); 066 float f1 = 0.01F / (float)par1Texture.getHeight(); 067 this.minU = (float)par3 / (float)par1Texture.getWidth() + f; 068 this.maxU = (float)(par3 + par5) / (float)par1Texture.getWidth() - f; 069 this.minV = (float)par4 / (float)par1Texture.getHeight() + f1; 070 this.maxV = (float)(par4 + par6) / (float)par1Texture.getHeight() - f1; 071 this.widthNorm = (float)par5 / 16.0F; 072 this.heightNorm = (float)par6 / 16.0F; 073 } 074 075 public void copyFrom(TextureStitched par1TextureStitched) 076 { 077 this.init(par1TextureStitched.textureSheet, par1TextureStitched.textureList, par1TextureStitched.originX, par1TextureStitched.originY, par1TextureStitched.width, par1TextureStitched.height, par1TextureStitched.rotated); 078 } 079 080 /** 081 * Returns the X position of this icon on its texture sheet, in pixels. 082 */ 083 public int getOriginX() 084 { 085 return this.originX; 086 } 087 088 /** 089 * Returns the Y position of this icon on its texture sheet, in pixels. 090 */ 091 public int getOriginY() 092 { 093 return this.originY; 094 } 095 096 /** 097 * Returns the minimum U coordinate to use when rendering with this icon. 098 */ 099 public float getMinU() 100 { 101 return this.minU; 102 } 103 104 /** 105 * Returns the maximum U coordinate to use when rendering with this icon. 106 */ 107 public float getMaxU() 108 { 109 return this.maxU; 110 } 111 112 /** 113 * Gets a U coordinate on the icon. 0 returns uMin and 16 returns uMax. Other arguments return in-between values. 114 */ 115 public float getInterpolatedU(double par1) 116 { 117 float f = this.maxU - this.minU; 118 return this.minU + f * ((float)par1 / 16.0F); 119 } 120 121 /** 122 * Returns the minimum V coordinate to use when rendering with this icon. 123 */ 124 public float getMinV() 125 { 126 return this.minV; 127 } 128 129 /** 130 * Returns the maximum V coordinate to use when rendering with this icon. 131 */ 132 public float getMaxV() 133 { 134 return this.maxV; 135 } 136 137 /** 138 * Gets a V coordinate on the icon. 0 returns vMin and 16 returns vMax. Other arguments return in-between values. 139 */ 140 public float getInterpolatedV(double par1) 141 { 142 float f = this.maxV - this.minV; 143 return this.minV + f * ((float)par1 / 16.0F); 144 } 145 146 public String getIconName() 147 { 148 return this.textureName; 149 } 150 151 /** 152 * Returns the width of the texture sheet this icon is on, in pixels. 153 */ 154 public int getSheetWidth() 155 { 156 return this.textureSheet.getWidth(); 157 } 158 159 /** 160 * Returns the height of the texture sheet this icon is on, in pixels. 161 */ 162 public int getSheetHeight() 163 { 164 return this.textureSheet.getHeight(); 165 } 166 167 public void updateAnimation() 168 { 169 if (this.listAnimationTuples != null) 170 { 171 Tuple tuple = (Tuple)this.listAnimationTuples.get(this.frameCounter); 172 ++this.tickCounter; 173 174 if (this.tickCounter >= ((Integer)tuple.getSecond()).intValue()) 175 { 176 int i = ((Integer)tuple.getFirst()).intValue(); 177 this.frameCounter = (this.frameCounter + 1) % this.listAnimationTuples.size(); 178 this.tickCounter = 0; 179 tuple = (Tuple)this.listAnimationTuples.get(this.frameCounter); 180 int j = ((Integer)tuple.getFirst()).intValue(); 181 182 if (i != j && j >= 0 && j < this.textureList.size()) 183 { 184 this.textureSheet.copyFrom(this.originX, this.originY, (Texture)this.textureList.get(j), this.rotated); 185 } 186 } 187 } 188 else 189 { 190 int k = this.frameCounter; 191 this.frameCounter = (this.frameCounter + 1) % this.textureList.size(); 192 193 if (k != this.frameCounter) 194 { 195 this.textureSheet.copyFrom(this.originX, this.originY, (Texture)this.textureList.get(this.frameCounter), this.rotated); 196 } 197 } 198 } 199 200 public void readAnimationInfo(BufferedReader par1BufferedReader) 201 { 202 ArrayList arraylist = new ArrayList(); 203 204 try 205 { 206 for (String s = par1BufferedReader.readLine(); s != null; s = par1BufferedReader.readLine()) 207 { 208 s = s.trim(); 209 210 if (s.length() > 0) 211 { 212 String[] astring = s.split(","); 213 String[] astring1 = astring; 214 int i = astring.length; 215 216 for (int j = 0; j < i; ++j) 217 { 218 String s1 = astring1[j]; 219 int k = s1.indexOf(42); 220 221 if (k > 0) 222 { 223 Integer integer = new Integer(s1.substring(0, k)); 224 Integer integer1 = new Integer(s1.substring(k + 1)); 225 arraylist.add(new Tuple(integer, integer1)); 226 } 227 else 228 { 229 arraylist.add(new Tuple(new Integer(s1), Integer.valueOf(1))); 230 } 231 } 232 } 233 } 234 } 235 catch (Exception exception) 236 { 237 System.err.println("Failed to read animation info for " + this.textureName + ": " + exception.getMessage()); 238 } 239 240 if (!arraylist.isEmpty() && arraylist.size() < 600) 241 { 242 this.listAnimationTuples = arraylist; 243 } 244 } 245 246 //=================================================================================================== 247 // Forge Start 248 //=================================================================================================== 249 /** 250 * Called when texture packs are refreshed, from TextureManager.createNewTexture, 251 * allows for finer control over loading the animation lists and verification of the image. 252 * If the return value from this is true, no further loading will be done by vanilla code. 253 * 254 * You need to add all Texture's to the textures argument. At the end of this function at least one 255 * entry should be in that argument, or a error should of been thrown. 256 * 257 * @param manager The invoking manager 258 * @param texturepack Current texture pack 259 * @param name The name of the texture 260 * @param fileName Resource path for this texture 261 * @param image Buffered image of the loaded resource 262 * @param textures ArrayList of element type Texture, split textures should be added to this list for the stitcher to handle. 263 * @return Return true to skip further vanilla texture loading for this texture 264 */ 265 public boolean loadTexture(TextureManager manager, ITexturePack texturepack, String name, String fileName, BufferedImage image, ArrayList textures) 266 { 267 return false; 268 } 269}