001    package net.minecraft.src;
002    
003    import cpw.mods.fml.common.Side;
004    import cpw.mods.fml.common.asm.SideOnly;
005    import java.util.Iterator;
006    import java.util.List;
007    
008    public class TileEntityBeacon extends TileEntity implements IInventory
009    {
010        /** List of effects that Beacon can apply */
011        public static final Potion[][] effectsList = new Potion[][] {{Potion.moveSpeed, Potion.digSpeed}, {Potion.resistance, Potion.jump}, {Potion.damageBoost}, {Potion.regeneration}};
012        @SideOnly(Side.CLIENT)
013        private long field_82137_b;
014        @SideOnly(Side.CLIENT)
015        private float field_82138_c;
016        private boolean field_82135_d;
017    
018        /** Level of this beacon's pyramid. */
019        private int levels = -1;
020    
021        /** Primary potion effect given by this beacon. */
022        private int primaryEffect;
023    
024        /** Secondary potion effect given by this beacon. */
025        private int secondaryEffect;
026    
027        /** Item given to this beacon as payment. */
028        private ItemStack payment;
029    
030        /**
031         * Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count
032         * ticks and creates a new spawn inside its implementation.
033         */
034        public void updateEntity()
035        {
036            if (this.worldObj.getTotalWorldTime() % 80L == 0L)
037            {
038                this.func_82131_u();
039                this.func_82124_t();
040            }
041        }
042    
043        private void func_82124_t()
044        {
045            if (this.field_82135_d && this.levels > 0 && !this.worldObj.isRemote && this.primaryEffect > 0)
046            {
047                double var1 = (double)(this.levels * 8 + 8);
048                byte var3 = 0;
049    
050                if (this.levels >= 4 && this.primaryEffect == this.secondaryEffect)
051                {
052                    var3 = 1;
053                }
054    
055                AxisAlignedBB var4 = AxisAlignedBB.getAABBPool().addOrModifyAABBInPool((double)this.xCoord, (double)this.yCoord, (double)this.zCoord, (double)(this.xCoord + 1), (double)(this.yCoord + 1), (double)(this.zCoord + 1)).expand(var1, var1, var1);
056                List var5 = this.worldObj.getEntitiesWithinAABB(EntityPlayer.class, var4);
057                Iterator var6 = var5.iterator();
058                EntityPlayer var7;
059    
060                while (var6.hasNext())
061                {
062                    var7 = (EntityPlayer)var6.next();
063                    var7.addPotionEffect(new PotionEffect(this.primaryEffect, 180, var3, true));
064                }
065    
066                if (this.levels >= 4 && this.primaryEffect != this.secondaryEffect && this.secondaryEffect > 0)
067                {
068                    var6 = var5.iterator();
069    
070                    while (var6.hasNext())
071                    {
072                        var7 = (EntityPlayer)var6.next();
073                        var7.addPotionEffect(new PotionEffect(this.secondaryEffect, 180, 0, true));
074                    }
075                }
076            }
077        }
078    
079        private void func_82131_u()
080        {
081            if (!this.worldObj.canBlockSeeTheSky(this.xCoord, this.yCoord + 1, this.zCoord))
082            {
083                this.field_82135_d = false;
084                this.levels = 0;
085            }
086            else
087            {
088                this.field_82135_d = true;
089                this.levels = 0;
090    
091                for (int var1 = 1; var1 <= 4; this.levels = var1++)
092                {
093                    int var2 = this.yCoord - var1;
094    
095                    if (var2 < 1)
096                    {
097                        break;
098                    }
099    
100                    boolean var3 = true;
101    
102                    for (int var4 = this.xCoord - var1; var4 <= this.xCoord + var1 && var3; ++var4)
103                    {
104                        for (int var5 = this.zCoord - var1; var5 <= this.zCoord + var1; ++var5)
105                        {
106                            int var6 = this.worldObj.getBlockId(var4, var2, var5);
107                            Block block = Block.blocksList[var6];
108    
109                            if (block == null || !block.isBeaconBase(worldObj, var4, var2, var5, xCoord, yCoord, zCoord))
110                            {
111                                var3 = false;
112                                break;
113                            }
114                        }
115                    }
116    
117                    if (!var3)
118                    {
119                        break;
120                    }
121                }
122    
123                if (this.levels == 0)
124                {
125                    this.field_82135_d = false;
126                }
127            }
128        }
129    
130        @SideOnly(Side.CLIENT)
131        public float func_82125_v_()
132        {
133            if (!this.field_82135_d)
134            {
135                return 0.0F;
136            }
137            else
138            {
139                int var1 = (int)(this.worldObj.getTotalWorldTime() - this.field_82137_b);
140                this.field_82137_b = this.worldObj.getTotalWorldTime();
141    
142                if (var1 > 1)
143                {
144                    this.field_82138_c -= (float)var1 / 40.0F;
145    
146                    if (this.field_82138_c < 0.0F)
147                    {
148                        this.field_82138_c = 0.0F;
149                    }
150                }
151    
152                this.field_82138_c += 0.025F;
153    
154                if (this.field_82138_c > 1.0F)
155                {
156                    this.field_82138_c = 1.0F;
157                }
158    
159                return this.field_82138_c;
160            }
161        }
162    
163        /**
164         * Return the primary potion effect given by this beacon.
165         */
166        public int getPrimaryEffect()
167        {
168            return this.primaryEffect;
169        }
170    
171        /**
172         * Return the secondary potion effect given by this beacon.
173         */
174        public int getSecondaryEffect()
175        {
176            return this.secondaryEffect;
177        }
178    
179        /**
180         * Return the levels of this beacon's pyramid.
181         */
182        public int getLevels()
183        {
184            return this.levels;
185        }
186    
187        @SideOnly(Side.CLIENT)
188    
189        /**
190         * Set the levels of this beacon's pyramid.
191         */
192        public void setLevels(int par1)
193        {
194            this.levels = par1;
195        }
196    
197        public void func_82128_d(int par1)
198        {
199            this.primaryEffect = 0;
200    
201            for (int var2 = 0; var2 < this.levels && var2 < 3; ++var2)
202            {
203                Potion[] var3 = effectsList[var2];
204                int var4 = var3.length;
205    
206                for (int var5 = 0; var5 < var4; ++var5)
207                {
208                    Potion var6 = var3[var5];
209    
210                    if (var6.id == par1)
211                    {
212                        this.primaryEffect = par1;
213                        return;
214                    }
215                }
216            }
217        }
218    
219        public void func_82127_e(int par1)
220        {
221            this.secondaryEffect = 0;
222    
223            if (this.levels >= 4)
224            {
225                for (int var2 = 0; var2 < 4; ++var2)
226                {
227                    Potion[] var3 = effectsList[var2];
228                    int var4 = var3.length;
229    
230                    for (int var5 = 0; var5 < var4; ++var5)
231                    {
232                        Potion var6 = var3[var5];
233    
234                        if (var6.id == par1)
235                        {
236                            this.secondaryEffect = par1;
237                            return;
238                        }
239                    }
240                }
241            }
242        }
243    
244        /**
245         * Overriden in a sign to provide the text.
246         */
247        public Packet getDescriptionPacket()
248        {
249            NBTTagCompound var1 = new NBTTagCompound();
250            this.writeToNBT(var1);
251            return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, 3, var1);
252        }
253    
254        @SideOnly(Side.CLIENT)
255        public double func_82115_m()
256        {
257            return 65536.0D;
258        }
259    
260        /**
261         * Reads a tile entity from NBT.
262         */
263        public void readFromNBT(NBTTagCompound par1NBTTagCompound)
264        {
265            super.readFromNBT(par1NBTTagCompound);
266            this.primaryEffect = par1NBTTagCompound.getInteger("Primary");
267            this.secondaryEffect = par1NBTTagCompound.getInteger("Secondary");
268            this.levels = par1NBTTagCompound.getInteger("Levels");
269        }
270    
271        /**
272         * Writes a tile entity to NBT.
273         */
274        public void writeToNBT(NBTTagCompound par1NBTTagCompound)
275        {
276            super.writeToNBT(par1NBTTagCompound);
277            par1NBTTagCompound.setInteger("Primary", this.primaryEffect);
278            par1NBTTagCompound.setInteger("Secondary", this.secondaryEffect);
279            par1NBTTagCompound.setInteger("Levels", this.levels);
280        }
281    
282        /**
283         * Returns the number of slots in the inventory.
284         */
285        public int getSizeInventory()
286        {
287            return 1;
288        }
289    
290        /**
291         * Returns the stack in slot i
292         */
293        public ItemStack getStackInSlot(int par1)
294        {
295            return par1 == 0 ? this.payment : null;
296        }
297    
298        /**
299         * Removes from an inventory slot (first arg) up to a specified number (second arg) of items and returns them in a
300         * new stack.
301         */
302        public ItemStack decrStackSize(int par1, int par2)
303        {
304            if (par1 == 0 && this.payment != null)
305            {
306                if (par2 >= this.payment.stackSize)
307                {
308                    ItemStack var3 = this.payment;
309                    this.payment = null;
310                    return var3;
311                }
312                else
313                {
314                    this.payment.stackSize -= par2;
315                    return new ItemStack(this.payment.itemID, par2, this.payment.getItemDamage());
316                }
317            }
318            else
319            {
320                return null;
321            }
322        }
323    
324        /**
325         * When some containers are closed they call this on each slot, then drop whatever it returns as an EntityItem -
326         * like when you close a workbench GUI.
327         */
328        public ItemStack getStackInSlotOnClosing(int par1)
329        {
330            if (par1 == 0 && this.payment != null)
331            {
332                ItemStack var2 = this.payment;
333                this.payment = null;
334                return var2;
335            }
336            else
337            {
338                return null;
339            }
340        }
341    
342        /**
343         * Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections).
344         */
345        public void setInventorySlotContents(int par1, ItemStack par2ItemStack)
346        {
347            if (par1 == 0)
348            {
349                this.payment = par2ItemStack;
350            }
351        }
352    
353        /**
354         * Returns the name of the inventory.
355         */
356        public String getInvName()
357        {
358            return "container.beacon";
359        }
360    
361        /**
362         * Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended. *Isn't
363         * this more of a set than a get?*
364         */
365        public int getInventoryStackLimit()
366        {
367            return 1;
368        }
369    
370        /**
371         * Do not make give this method the name canInteractWith because it clashes with Container
372         */
373        public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer)
374        {
375            return this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false : par1EntityPlayer.getDistanceSq((double)this.xCoord + 0.5D, (double)this.yCoord + 0.5D, (double)this.zCoord + 0.5D) <= 64.0D;
376        }
377    
378        public void openChest() {}
379    
380        public void closeChest() {}
381    }