001 package net.minecraft.inventory;
002
003 import cpw.mods.fml.relauncher.Side;
004 import cpw.mods.fml.relauncher.SideOnly;
005 import java.util.List;
006 import java.util.Random;
007 import net.minecraft.block.Block;
008 import net.minecraft.enchantment.EnchantmentData;
009 import net.minecraft.enchantment.EnchantmentHelper;
010 import net.minecraft.entity.player.EntityPlayer;
011 import net.minecraft.entity.player.InventoryPlayer;
012 import net.minecraft.item.Item;
013 import net.minecraft.item.ItemStack;
014 import net.minecraft.world.World;
015
016 public class ContainerEnchantment extends Container
017 {
018 /** SlotEnchantmentTable object with ItemStack to be enchanted */
019 public IInventory tableInventory = new SlotEnchantmentTable(this, "Enchant", 1);
020
021 /** current world (for bookshelf counting) */
022 private World worldPointer;
023 private int posX;
024 private int posY;
025 private int posZ;
026 private Random rand = new Random();
027
028 /** used as seed for EnchantmentNameParts (see GuiEnchantment) */
029 public long nameSeed;
030
031 /** 3-member array storing the enchantment levels of each slot */
032 public int[] enchantLevels = new int[3];
033
034 public ContainerEnchantment(InventoryPlayer par1InventoryPlayer, World par2World, int par3, int par4, int par5)
035 {
036 this.worldPointer = par2World;
037 this.posX = par3;
038 this.posY = par4;
039 this.posZ = par5;
040 this.addSlotToContainer(new SlotEnchantment(this, this.tableInventory, 0, 25, 47));
041 int var6;
042
043 for (var6 = 0; var6 < 3; ++var6)
044 {
045 for (int var7 = 0; var7 < 9; ++var7)
046 {
047 this.addSlotToContainer(new Slot(par1InventoryPlayer, var7 + var6 * 9 + 9, 8 + var7 * 18, 84 + var6 * 18));
048 }
049 }
050
051 for (var6 = 0; var6 < 9; ++var6)
052 {
053 this.addSlotToContainer(new Slot(par1InventoryPlayer, var6, 8 + var6 * 18, 142));
054 }
055 }
056
057 public void addCraftingToCrafters(ICrafting par1ICrafting)
058 {
059 super.addCraftingToCrafters(par1ICrafting);
060 par1ICrafting.sendProgressBarUpdate(this, 0, this.enchantLevels[0]);
061 par1ICrafting.sendProgressBarUpdate(this, 1, this.enchantLevels[1]);
062 par1ICrafting.sendProgressBarUpdate(this, 2, this.enchantLevels[2]);
063 }
064
065 /**
066 * Looks for changes made in the container, sends them to every listener.
067 */
068 public void detectAndSendChanges()
069 {
070 super.detectAndSendChanges();
071
072 for (int var1 = 0; var1 < this.crafters.size(); ++var1)
073 {
074 ICrafting var2 = (ICrafting)this.crafters.get(var1);
075 var2.sendProgressBarUpdate(this, 0, this.enchantLevels[0]);
076 var2.sendProgressBarUpdate(this, 1, this.enchantLevels[1]);
077 var2.sendProgressBarUpdate(this, 2, this.enchantLevels[2]);
078 }
079 }
080
081 @SideOnly(Side.CLIENT)
082 public void updateProgressBar(int par1, int par2)
083 {
084 if (par1 >= 0 && par1 <= 2)
085 {
086 this.enchantLevels[par1] = par2;
087 }
088 else
089 {
090 super.updateProgressBar(par1, par2);
091 }
092 }
093
094 /**
095 * Callback for when the crafting matrix is changed.
096 */
097 public void onCraftMatrixChanged(IInventory par1IInventory)
098 {
099 if (par1IInventory == this.tableInventory)
100 {
101 ItemStack var2 = par1IInventory.getStackInSlot(0);
102 int var3;
103
104 if (var2 != null && var2.isItemEnchantable())
105 {
106 this.nameSeed = this.rand.nextLong();
107
108 if (!this.worldPointer.isRemote)
109 {
110 var3 = 0;
111 int var4;
112
113 for (var4 = -1; var4 <= 1; ++var4)
114 {
115 for (int var5 = -1; var5 <= 1; ++var5)
116 {
117 if ((var4 != 0 || var5 != 0) && this.worldPointer.isAirBlock(this.posX + var5, this.posY, this.posZ + var4) && this.worldPointer.isAirBlock(this.posX + var5, this.posY + 1, this.posZ + var4))
118 {
119 if (this.worldPointer.getBlockId(this.posX + var5 * 2, this.posY, this.posZ + var4 * 2) == Block.bookShelf.blockID)
120 {
121 ++var3;
122 }
123
124 if (this.worldPointer.getBlockId(this.posX + var5 * 2, this.posY + 1, this.posZ + var4 * 2) == Block.bookShelf.blockID)
125 {
126 ++var3;
127 }
128
129 if (var5 != 0 && var4 != 0)
130 {
131 if (this.worldPointer.getBlockId(this.posX + var5 * 2, this.posY, this.posZ + var4) == Block.bookShelf.blockID)
132 {
133 ++var3;
134 }
135
136 if (this.worldPointer.getBlockId(this.posX + var5 * 2, this.posY + 1, this.posZ + var4) == Block.bookShelf.blockID)
137 {
138 ++var3;
139 }
140
141 if (this.worldPointer.getBlockId(this.posX + var5, this.posY, this.posZ + var4 * 2) == Block.bookShelf.blockID)
142 {
143 ++var3;
144 }
145
146 if (this.worldPointer.getBlockId(this.posX + var5, this.posY + 1, this.posZ + var4 * 2) == Block.bookShelf.blockID)
147 {
148 ++var3;
149 }
150 }
151 }
152 }
153 }
154
155 for (var4 = 0; var4 < 3; ++var4)
156 {
157 this.enchantLevels[var4] = EnchantmentHelper.calcItemStackEnchantability(this.rand, var4, var3, var2);
158 }
159
160 this.detectAndSendChanges();
161 }
162 }
163 else
164 {
165 for (var3 = 0; var3 < 3; ++var3)
166 {
167 this.enchantLevels[var3] = 0;
168 }
169 }
170 }
171 }
172
173 /**
174 * enchants the item on the table using the specified slot; also deducts XP from player
175 */
176 public boolean enchantItem(EntityPlayer par1EntityPlayer, int par2)
177 {
178 ItemStack var3 = this.tableInventory.getStackInSlot(0);
179
180 if (this.enchantLevels[par2] > 0 && var3 != null && (par1EntityPlayer.experienceLevel >= this.enchantLevels[par2] || par1EntityPlayer.capabilities.isCreativeMode))
181 {
182 if (!this.worldPointer.isRemote)
183 {
184 List var4 = EnchantmentHelper.buildEnchantmentList(this.rand, var3, this.enchantLevels[par2]);
185 boolean var5 = var3.itemID == Item.book.itemID;
186
187 if (var4 != null)
188 {
189 par1EntityPlayer.addExperienceLevel(-this.enchantLevels[par2]);
190
191 if (var5)
192 {
193 var3.itemID = Item.field_92053_bW.itemID;
194 }
195
196 int var6 = var5 ? this.rand.nextInt(var4.size()) : -1;
197
198 for (int var7 = 0; var7 < var4.size(); ++var7)
199 {
200 EnchantmentData var8 = (EnchantmentData)var4.get(var7);
201
202 if (!var5 || var7 == var6)
203 {
204 if (var5)
205 {
206 Item.field_92053_bW.func_92060_a(var3, var8);
207 }
208 else
209 {
210 var3.addEnchantment(var8.enchantmentobj, var8.enchantmentLevel);
211 }
212 }
213 }
214
215 this.onCraftMatrixChanged(this.tableInventory);
216 }
217 }
218
219 return true;
220 }
221 else
222 {
223 return false;
224 }
225 }
226
227 /**
228 * Callback for when the crafting gui is closed.
229 */
230 public void onCraftGuiClosed(EntityPlayer par1EntityPlayer)
231 {
232 super.onCraftGuiClosed(par1EntityPlayer);
233
234 if (!this.worldPointer.isRemote)
235 {
236 ItemStack var2 = this.tableInventory.getStackInSlotOnClosing(0);
237
238 if (var2 != null)
239 {
240 par1EntityPlayer.dropPlayerItem(var2);
241 }
242 }
243 }
244
245 public boolean canInteractWith(EntityPlayer par1EntityPlayer)
246 {
247 return this.worldPointer.getBlockId(this.posX, this.posY, this.posZ) != Block.enchantmentTable.blockID ? false : par1EntityPlayer.getDistanceSq((double)this.posX + 0.5D, (double)this.posY + 0.5D, (double)this.posZ + 0.5D) <= 64.0D;
248 }
249
250 /**
251 * Called when a player shift-clicks on a slot. You must override this or you will crash when someone does that.
252 */
253 public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2)
254 {
255 ItemStack var3 = null;
256 Slot var4 = (Slot)this.inventorySlots.get(par2);
257
258 if (var4 != null && var4.getHasStack())
259 {
260 ItemStack var5 = var4.getStack();
261 var3 = var5.copy();
262
263 if (par2 == 0)
264 {
265 if (!this.mergeItemStack(var5, 1, 37, true))
266 {
267 return null;
268 }
269 }
270 else
271 {
272 if (((Slot)this.inventorySlots.get(0)).getHasStack() || !((Slot)this.inventorySlots.get(0)).isItemValid(var5))
273 {
274 return null;
275 }
276
277 if (var5.hasTagCompound() && var5.stackSize == 1)
278 {
279 ((Slot)this.inventorySlots.get(0)).putStack(var5.copy());
280 var5.stackSize = 0;
281 }
282 else if (var5.stackSize >= 1)
283 {
284 ((Slot)this.inventorySlots.get(0)).putStack(new ItemStack(var5.itemID, 1, var5.getItemDamage()));
285 --var5.stackSize;
286 }
287 }
288
289 if (var5.stackSize == 0)
290 {
291 var4.putStack((ItemStack)null);
292 }
293 else
294 {
295 var4.onSlotChanged();
296 }
297
298 if (var5.stackSize == var3.stackSize)
299 {
300 return null;
301 }
302
303 var4.onPickupFromSlot(par1EntityPlayer, var5);
304 }
305
306 return var3;
307 }
308 }