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 }