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 }