001package net.minecraftforge.liquids; 002 003import static cpw.mods.fml.relauncher.Side.CLIENT; 004 005import com.google.common.base.Objects; 006 007import cpw.mods.fml.relauncher.SideOnly; 008import net.minecraft.block.Block; 009import net.minecraft.block.BlockFluid; 010import net.minecraft.client.renderer.texture.TextureManager; 011import net.minecraft.item.Item; 012import net.minecraft.item.ItemStack; 013import net.minecraft.nbt.NBTTagCompound; 014import net.minecraft.util.Icon; 015 016/** 017 * ItemStack substitute for liquids 018 * Things of note: they are equal if their items are equal. Amount does NOT matter for java equals() testing 019 * <br/> 020 * The canonical liquidstack is probably the only one that has a lot of the rendering data on it. Use {@link #canonical()} 021 * to get it. 022 * 023 * @author SirSengir 024 */ 025public class LiquidStack 026{ 027 public final int itemID; 028 public int amount; 029 public final int itemMeta; 030 public NBTTagCompound extra; 031 032 public LiquidStack(int itemID, int amount) { this(itemID, amount, 0); } 033 public LiquidStack(Item item, int amount) { this(item.itemID, amount, 0); } 034 public LiquidStack(Block block, int amount) { this(block.blockID, amount, 0); } 035 036 public LiquidStack(int itemID, int amount, int itemDamage) 037 { 038 this.itemID = itemID; 039 this.amount = amount; 040 this.itemMeta = itemDamage; 041 } 042 043 public LiquidStack(int itemID, int amount, int itemDamage, NBTTagCompound nbt) 044 { 045 this(itemID, amount, itemDamage); 046 if (nbt != null) 047 { 048 extra = (NBTTagCompound)nbt.copy(); 049 } 050 } 051 052 public NBTTagCompound writeToNBT(NBTTagCompound nbt) 053 { 054 nbt.setInteger("Amount", amount); 055 nbt.setShort("Id", (short)itemID); 056 nbt.setShort("Meta", (short)itemMeta); 057 nbt.setString("LiquidName", LiquidDictionary.findLiquidName(this)); 058 if (extra != null) 059 { 060 nbt.setTag("extra", extra); 061 } 062 return nbt; 063 } 064 065 066 /** 067 * NO-OP now. Use {@link #loadLiquidStackFromNBT(NBTTagCompound)} to get a new instance 068 * 069 * @param nbt 070 */ 071 @Deprecated 072 public void readFromNBT(NBTTagCompound nbt) 073 { 074 } 075 076 /** 077 * @return A copy of this LiquidStack 078 */ 079 public LiquidStack copy() 080 { 081 return new LiquidStack(itemID, amount, itemMeta, extra); 082 } 083 084 /** 085 * @param other 086 * @return true if this LiquidStack contains the same liquid as the one passed in. 087 */ 088 public boolean isLiquidEqual(LiquidStack other) 089 { 090 return other != null && itemID == other.itemID && itemMeta == other.itemMeta && (extra == null ? other.extra == null : extra.equals(other.extra)); 091 } 092 093 /** 094 * @param other 095 * @return true if this LiquidStack contains the other liquid (liquids are equal and amount >= other.amount). 096 */ 097 public boolean containsLiquid(LiquidStack other) 098 { 099 return isLiquidEqual(other) && amount >= other.amount; 100 } 101 102 /** 103 * @param other ItemStack containing liquids. 104 * @return true if this LiquidStack contains the same liquid as the one passed in. 105 */ 106 public boolean isLiquidEqual(ItemStack other) 107 { 108 if (other == null) 109 { 110 return false; 111 } 112 113 if (itemID == other.itemID && itemMeta == other.getItemDamage()) 114 { 115 return true; 116 } 117 118 return isLiquidEqual(LiquidContainerRegistry.getLiquidForFilledItem(other)); 119 } 120 121 /** 122 * @return ItemStack representation of this LiquidStack 123 */ 124 public ItemStack asItemStack() 125 { 126 ItemStack stack = new ItemStack(itemID, 1, itemMeta); 127 if (extra != null) 128 { 129 stack.stackTagCompound = (NBTTagCompound)extra.copy(); 130 } 131 return stack; 132 } 133 134 /** 135 * Reads a liquid stack from the passed nbttagcompound and returns it. 136 * 137 * @param nbt 138 * @return the liquid stack 139 */ 140 public static LiquidStack loadLiquidStackFromNBT(NBTTagCompound nbt) 141 { 142 if (nbt == null) 143 { 144 return null; 145 } 146 String liquidName = nbt.getString("LiquidName"); 147 int itemID = nbt.getShort("Id"); 148 int itemMeta = nbt.getShort("Meta"); 149 LiquidStack liquid = LiquidDictionary.getCanonicalLiquid(liquidName); 150 if(liquid != null) { 151 itemID = liquid.itemID; 152 itemMeta = liquid.itemMeta; 153 } 154 // if the item is not existent, and no liquid dictionary is found, null returns 155 else if (Item.itemsList[itemID] == null) 156 { 157 return null; 158 } 159 int amount = nbt.getInteger("Amount"); 160 LiquidStack liquidstack = new LiquidStack(itemID, amount, itemMeta); 161 if (nbt.hasKey("extra")) 162 { 163 liquidstack.extra = nbt.getCompoundTag("extra"); 164 } 165 return liquidstack.itemID == 0 ? null : liquidstack; 166 } 167 168 private String textureSheet = "/terrain.png"; 169 170 /** 171 * Return the textureSheet used for this liquid stack's texture Icon 172 * Defaults to '/terrain.png' 173 * 174 * See {@link #getRenderingIcon()} for the actual icon 175 * 176 * @return The texture sheet 177 */ 178 public String getTextureSheet() 179 { 180 return textureSheet; 181 } 182 183 /** 184 * Set the texture sheet for this icon (usually /terrain.png or /gui/items.png) 185 * 186 * See also the {@link #setRenderingIcon(Icon)} for the icon itself 187 * 188 * @param textureSheet 189 * @return the liquid stack 190 */ 191 public LiquidStack setTextureSheet(String textureSheet) 192 { 193 this.textureSheet = textureSheet; 194 return this; 195 } 196 @SideOnly(CLIENT) 197 private Icon renderingIcon; 198 199 /** 200 * Get the rendering icon for this liquid stack, for presentation in the world or in GUIs. 201 * Defaults to handling water and lava, and returns the set rendering icon otherwise. 202 * 203 * See {@link #getTextureSheet()} to get the texture sheet this icon is associated with 204 * 205 * @return The icon for rendering this liquid 206 */ 207 @SideOnly(CLIENT) 208 public Icon getRenderingIcon() 209 { 210 if (itemID == Block.waterStill.blockID) 211 { 212 return BlockFluid.func_94424_b("water"); 213 } 214 else if (itemID == Block.lavaStill.blockID) 215 { 216 return BlockFluid.func_94424_b("lava"); 217 } 218 return renderingIcon; 219 } 220 221 /** 222 * Set the icon for rendering this liquid 223 * It should be refreshed whenever textures are refreshed. 224 * 225 * See also {@link #setTextureSheet(String)} for setting the sheet this icon is associated with 226 * 227 * @param icon The icon to render 228 * @return The liquid stack 229 */ 230 @SideOnly(CLIENT) 231 public LiquidStack setRenderingIcon(Icon icon) 232 { 233 this.renderingIcon = icon; 234 return this; 235 } 236 237 @Override 238 public final int hashCode() 239 { 240 return 31 * itemMeta + itemID; 241 } 242 243 @Override 244 public final boolean equals(Object ob) 245 { 246 if (ob instanceof LiquidStack) 247 { 248 LiquidStack ls = (LiquidStack)ob; 249 return ls.itemID == itemID && ls.itemMeta == itemMeta && (extra == null ? ls.extra == null : extra.equals(ls.extra)); 250 } 251 return false; 252 } 253 254 255 /** 256 * Get the canonical version of this liquid stack (will contain things like icons and texturesheets) 257 * @return The canonical liquidstack 258 */ 259 public LiquidStack canonical() 260 { 261 return LiquidDictionary.getCanonicalLiquid(this); 262 } 263}