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 031 public LiquidStack(int itemID, int amount) { this(itemID, amount, 0); } 032 public LiquidStack(Item item, int amount) { this(item.itemID, amount, 0); } 033 public LiquidStack(Block block, int amount) { this(block.blockID, amount, 0); } 034 035 public LiquidStack(int itemID, int amount, int itemDamage) 036 { 037 this.itemID = itemID; 038 this.amount = amount; 039 this.itemMeta = itemDamage; 040 } 041 042 public NBTTagCompound writeToNBT(NBTTagCompound nbt) 043 { 044 nbt.setInteger("Amount", amount); 045 nbt.setShort("Id", (short)itemID); 046 nbt.setShort("Meta", (short)itemMeta); 047 nbt.setString("LiquidName", LiquidDictionary.findLiquidName(this)); 048 return nbt; 049 } 050 051 052 /** 053 * NO-OP now. Use {@link #loadLiquidStackFromNBT(NBTTagCompound)} to get a new instance 054 * 055 * @param nbt 056 */ 057 @Deprecated 058 public void readFromNBT(NBTTagCompound nbt) 059 { 060 } 061 062 /** 063 * @return A copy of this LiquidStack 064 */ 065 public LiquidStack copy() 066 { 067 return new LiquidStack(itemID, amount, itemMeta); 068 } 069 070 /** 071 * @param other 072 * @return true if this LiquidStack contains the same liquid as the one passed in. 073 */ 074 public boolean isLiquidEqual(LiquidStack other) 075 { 076 return other != null && itemID == other.itemID && itemMeta == other.itemMeta; 077 } 078 079 /** 080 * @param other 081 * @return true if this LiquidStack contains the other liquid (liquids are equal and amount >= other.amount). 082 */ 083 public boolean containsLiquid(LiquidStack other) 084 { 085 return isLiquidEqual(other) && amount >= other.amount; 086 } 087 088 /** 089 * @param other ItemStack containing liquids. 090 * @return true if this LiquidStack contains the same liquid as the one passed in. 091 */ 092 public boolean isLiquidEqual(ItemStack other) 093 { 094 if (other == null) 095 { 096 return false; 097 } 098 099 if (itemID == other.itemID && itemMeta == other.getItemDamage()) 100 { 101 return true; 102 } 103 104 return isLiquidEqual(LiquidContainerRegistry.getLiquidForFilledItem(other)); 105 } 106 107 /** 108 * @return ItemStack representation of this LiquidStack 109 */ 110 public ItemStack asItemStack() 111 { 112 return new ItemStack(itemID, 1, itemMeta); 113 } 114 115 /** 116 * Reads a liquid stack from the passed nbttagcompound and returns it. 117 * 118 * @param nbt 119 * @return the liquid stack 120 */ 121 public static LiquidStack loadLiquidStackFromNBT(NBTTagCompound nbt) 122 { 123 if (nbt == null) 124 { 125 return null; 126 } 127 String liquidName = nbt.getString("LiquidName"); 128 int itemID = nbt.getShort("Id"); 129 int itemMeta = nbt.getShort("Meta"); 130 LiquidStack liquid = LiquidDictionary.getCanonicalLiquid(liquidName); 131 if(liquid != null) { 132 itemID = liquid.itemID; 133 itemMeta = liquid.itemMeta; 134 } 135 // if the item is not existent, and no liquid dictionary is found, null returns 136 else if (Item.itemsList[itemID] == null) 137 { 138 return null; 139 } 140 int amount = nbt.getInteger("Amount"); 141 LiquidStack liquidstack = new LiquidStack(itemID, amount, itemMeta); 142 return liquidstack.itemID == 0 ? null : liquidstack; 143 } 144 145 private String textureSheet = "/terrain.png"; 146 147 /** 148 * Return the textureSheet used for this liquid stack's texture Icon 149 * Defaults to '/terrain.png' 150 * 151 * See {@link #getRenderingIcon()} for the actual icon 152 * 153 * @return The texture sheet 154 */ 155 public String getTextureSheet() 156 { 157 return textureSheet; 158 } 159 160 /** 161 * Set the texture sheet for this icon (usually /terrain.png or /gui/items.png) 162 * 163 * See also the {@link #setRenderingIcon(Icon)} for the icon itself 164 * 165 * @param textureSheet 166 * @return the liquid stack 167 */ 168 public LiquidStack setTextureSheet(String textureSheet) 169 { 170 this.textureSheet = textureSheet; 171 return this; 172 } 173 @SideOnly(CLIENT) 174 private Icon renderingIcon; 175 176 /** 177 * Get the rendering icon for this liquid stack, for presentation in the world or in GUIs. 178 * Defaults to handling water and lava, and returns the set rendering icon otherwise. 179 * 180 * See {@link #getTextureSheet()} to get the texture sheet this icon is associated with 181 * 182 * @return The icon for rendering this liquid 183 */ 184 @SideOnly(CLIENT) 185 public Icon getRenderingIcon() 186 { 187 if (itemID == Block.waterStill.blockID) 188 { 189 return BlockFluid.func_94424_b("water"); 190 } 191 else if (itemID == Block.lavaStill.blockID) 192 { 193 return BlockFluid.func_94424_b("lava"); 194 } 195 return renderingIcon; 196 } 197 198 /** 199 * Set the icon for rendering this liquid 200 * It should be refreshed whenever textures are refreshed. 201 * 202 * See also {@link #setTextureSheet(String)} for setting the sheet this icon is associated with 203 * 204 * @param icon The icon to render 205 * @return The liquid stack 206 */ 207 @SideOnly(CLIENT) 208 public LiquidStack setRenderingIcon(Icon icon) 209 { 210 this.renderingIcon = icon; 211 return this; 212 } 213 214 @Override 215 public final int hashCode() 216 { 217 return 31 * itemMeta + itemID; 218 } 219 220 @Override 221 public final boolean equals(Object ob) 222 { 223 if (ob instanceof LiquidStack) 224 { 225 LiquidStack ls = (LiquidStack)ob; 226 return ls.itemID == itemID && ls.itemMeta == itemMeta; 227 } 228 return false; 229 } 230 231 232 /** 233 * Get the canonical version of this liquid stack (will contain things like icons and texturesheets) 234 * @return The canonical liquidstack 235 */ 236 public LiquidStack canonical() 237 { 238 return LiquidDictionary.getCanonicalLiquid(this); 239 } 240}