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    }