001package net.minecraft.entity.item; 002 003import net.minecraft.entity.player.EntityPlayer; 004import net.minecraft.inventory.Container; 005import net.minecraft.inventory.IInventory; 006import net.minecraft.item.ItemStack; 007import net.minecraft.nbt.NBTTagCompound; 008import net.minecraft.nbt.NBTTagList; 009import net.minecraft.util.DamageSource; 010import net.minecraft.world.World; 011import net.minecraftforge.common.MinecraftForge; 012import net.minecraftforge.event.entity.minecart.MinecartInteractEvent; 013 014public abstract class EntityMinecartContainer extends EntityMinecart implements IInventory 015{ 016 private ItemStack[] field_94113_a = new ItemStack[36]; 017 private boolean field_94112_b = true; 018 019 public EntityMinecartContainer(World par1World) 020 { 021 super(par1World); 022 } 023 024 public EntityMinecartContainer(World par1World, double par2, double par4, double par6) 025 { 026 super(par1World, par2, par4, par6); 027 } 028 029 public void func_94095_a(DamageSource par1DamageSource) 030 { 031 super.func_94095_a(par1DamageSource); 032 033 for (int i = 0; i < this.getSizeInventory(); ++i) 034 { 035 ItemStack itemstack = this.getStackInSlot(i); 036 037 if (itemstack != null) 038 { 039 float f = this.rand.nextFloat() * 0.8F + 0.1F; 040 float f1 = this.rand.nextFloat() * 0.8F + 0.1F; 041 float f2 = this.rand.nextFloat() * 0.8F + 0.1F; 042 043 while (itemstack.stackSize > 0) 044 { 045 int j = this.rand.nextInt(21) + 10; 046 047 if (j > itemstack.stackSize) 048 { 049 j = itemstack.stackSize; 050 } 051 052 itemstack.stackSize -= j; 053 EntityItem entityitem = new EntityItem(this.worldObj, this.posX + (double)f, this.posY + (double)f1, this.posZ + (double)f2, new ItemStack(itemstack.itemID, j, itemstack.getItemDamage())); 054 float f3 = 0.05F; 055 entityitem.motionX = (double)((float)this.rand.nextGaussian() * f3); 056 entityitem.motionY = (double)((float)this.rand.nextGaussian() * f3 + 0.2F); 057 entityitem.motionZ = (double)((float)this.rand.nextGaussian() * f3); 058 this.worldObj.spawnEntityInWorld(entityitem); 059 } 060 } 061 } 062 } 063 064 /** 065 * Returns the stack in slot i 066 */ 067 public ItemStack getStackInSlot(int par1) 068 { 069 return this.field_94113_a[par1]; 070 } 071 072 /** 073 * Removes from an inventory slot (first arg) up to a specified number (second arg) of items and returns them in a 074 * new stack. 075 */ 076 public ItemStack decrStackSize(int par1, int par2) 077 { 078 if (this.field_94113_a[par1] != null) 079 { 080 ItemStack itemstack; 081 082 if (this.field_94113_a[par1].stackSize <= par2) 083 { 084 itemstack = this.field_94113_a[par1]; 085 this.field_94113_a[par1] = null; 086 return itemstack; 087 } 088 else 089 { 090 itemstack = this.field_94113_a[par1].splitStack(par2); 091 092 if (this.field_94113_a[par1].stackSize == 0) 093 { 094 this.field_94113_a[par1] = null; 095 } 096 097 return itemstack; 098 } 099 } 100 else 101 { 102 return null; 103 } 104 } 105 106 /** 107 * When some containers are closed they call this on each slot, then drop whatever it returns as an EntityItem - 108 * like when you close a workbench GUI. 109 */ 110 public ItemStack getStackInSlotOnClosing(int par1) 111 { 112 if (this.field_94113_a[par1] != null) 113 { 114 ItemStack itemstack = this.field_94113_a[par1]; 115 this.field_94113_a[par1] = null; 116 return itemstack; 117 } 118 else 119 { 120 return null; 121 } 122 } 123 124 /** 125 * Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections). 126 */ 127 public void setInventorySlotContents(int par1, ItemStack par2ItemStack) 128 { 129 this.field_94113_a[par1] = par2ItemStack; 130 131 if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit()) 132 { 133 par2ItemStack.stackSize = this.getInventoryStackLimit(); 134 } 135 } 136 137 /** 138 * Called when an the contents of an Inventory change, usually 139 */ 140 public void onInventoryChanged() {} 141 142 /** 143 * Do not make give this method the name canInteractWith because it clashes with Container 144 */ 145 public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) 146 { 147 return this.isDead ? false : par1EntityPlayer.getDistanceSqToEntity(this) <= 64.0D; 148 } 149 150 public void openChest() {} 151 152 public void closeChest() {} 153 154 public boolean func_94041_b(int par1, ItemStack par2ItemStack) 155 { 156 return true; 157 } 158 159 /** 160 * Returns the name of the inventory. 161 */ 162 public String getInvName() 163 { 164 return this.func_94042_c() ? this.func_95999_t() : "container.minecart"; 165 } 166 167 /** 168 * Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended. *Isn't 169 * this more of a set than a get?* 170 */ 171 public int getInventoryStackLimit() 172 { 173 return 64; 174 } 175 176 /** 177 * Teleports the entity to another dimension. Params: Dimension number to teleport to 178 */ 179 public void travelToDimension(int par1) 180 { 181 this.field_94112_b = false; 182 super.travelToDimension(par1); 183 } 184 185 /** 186 * Will get destroyed next tick. 187 */ 188 public void setDead() 189 { 190 if (this.field_94112_b) 191 { 192 for (int i = 0; i < this.getSizeInventory(); ++i) 193 { 194 ItemStack itemstack = this.getStackInSlot(i); 195 196 if (itemstack != null) 197 { 198 float f = this.rand.nextFloat() * 0.8F + 0.1F; 199 float f1 = this.rand.nextFloat() * 0.8F + 0.1F; 200 float f2 = this.rand.nextFloat() * 0.8F + 0.1F; 201 202 while (itemstack.stackSize > 0) 203 { 204 int j = this.rand.nextInt(21) + 10; 205 206 if (j > itemstack.stackSize) 207 { 208 j = itemstack.stackSize; 209 } 210 211 itemstack.stackSize -= j; 212 EntityItem entityitem = new EntityItem(this.worldObj, this.posX + (double)f, this.posY + (double)f1, this.posZ + (double)f2, new ItemStack(itemstack.itemID, j, itemstack.getItemDamage())); 213 214 if (itemstack.hasTagCompound()) 215 { 216 entityitem.getEntityItem().setTagCompound((NBTTagCompound)itemstack.getTagCompound().copy()); 217 } 218 219 float f3 = 0.05F; 220 entityitem.motionX = (double)((float)this.rand.nextGaussian() * f3); 221 entityitem.motionY = (double)((float)this.rand.nextGaussian() * f3 + 0.2F); 222 entityitem.motionZ = (double)((float)this.rand.nextGaussian() * f3); 223 this.worldObj.spawnEntityInWorld(entityitem); 224 } 225 } 226 } 227 } 228 229 super.setDead(); 230 } 231 232 /** 233 * (abstract) Protected helper method to write subclass entity data to NBT. 234 */ 235 protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) 236 { 237 super.writeEntityToNBT(par1NBTTagCompound); 238 NBTTagList nbttaglist = new NBTTagList(); 239 240 for (int i = 0; i < this.field_94113_a.length; ++i) 241 { 242 if (this.field_94113_a[i] != null) 243 { 244 NBTTagCompound nbttagcompound1 = new NBTTagCompound(); 245 nbttagcompound1.setByte("Slot", (byte)i); 246 this.field_94113_a[i].writeToNBT(nbttagcompound1); 247 nbttaglist.appendTag(nbttagcompound1); 248 } 249 } 250 251 par1NBTTagCompound.setTag("Items", nbttaglist); 252 } 253 254 /** 255 * (abstract) Protected helper method to read subclass entity data from NBT. 256 */ 257 protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) 258 { 259 super.readEntityFromNBT(par1NBTTagCompound); 260 NBTTagList nbttaglist = par1NBTTagCompound.getTagList("Items"); 261 this.field_94113_a = new ItemStack[this.getSizeInventory()]; 262 263 for (int i = 0; i < nbttaglist.tagCount(); ++i) 264 { 265 NBTTagCompound nbttagcompound1 = (NBTTagCompound)nbttaglist.tagAt(i); 266 int j = nbttagcompound1.getByte("Slot") & 255; 267 268 if (j >= 0 && j < this.field_94113_a.length) 269 { 270 this.field_94113_a[j] = ItemStack.loadItemStackFromNBT(nbttagcompound1); 271 } 272 } 273 } 274 275 /** 276 * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig. 277 */ 278 public boolean interact(EntityPlayer par1EntityPlayer) 279 { 280 if(MinecraftForge.EVENT_BUS.post(new MinecartInteractEvent(this, par1EntityPlayer))) 281 { 282 return true; 283 } 284 if (!this.worldObj.isRemote) 285 { 286 par1EntityPlayer.displayGUIChest(this); 287 } 288 289 return true; 290 } 291 292 protected void func_94101_h() 293 { 294 int i = 15 - Container.func_94526_b(this); 295 float f = 0.98F + (float)i * 0.001F; 296 this.motionX *= (double)f; 297 this.motionY *= 0.0D; 298 this.motionZ *= (double)f; 299 } 300}