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.ArrayList; 006 import java.util.HashMap; 007 import java.util.List; 008 import java.util.Map; 009 import java.util.Random; 010 011 public class BlockRedstoneTorch extends BlockTorch 012 { 013 /** Whether the redstone torch is currently active or not. */ 014 private boolean torchActive = false; 015 016 /** Map of ArrayLists of RedstoneUpdateInfo. Key of map is World. */ 017 private static Map redstoneUpdateInfoCache = new HashMap(); 018 019 /** 020 * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata 021 */ 022 public int getBlockTextureFromSideAndMetadata(int par1, int par2) 023 { 024 return par1 == 1 ? Block.redstoneWire.getBlockTextureFromSideAndMetadata(par1, par2) : super.getBlockTextureFromSideAndMetadata(par1, par2); 025 } 026 027 private boolean checkForBurnout(World par1World, int par2, int par3, int par4, boolean par5) 028 { 029 if (!redstoneUpdateInfoCache.containsKey(par1World)) 030 { 031 redstoneUpdateInfoCache.put(par1World, new ArrayList()); 032 } 033 034 List var6 = (List)redstoneUpdateInfoCache.get(par1World); 035 036 if (par5) 037 { 038 var6.add(new RedstoneUpdateInfo(par2, par3, par4, par1World.getTotalWorldTime())); 039 } 040 041 int var7 = 0; 042 043 for (int var8 = 0; var8 < var6.size(); ++var8) 044 { 045 RedstoneUpdateInfo var9 = (RedstoneUpdateInfo)var6.get(var8); 046 047 if (var9.x == par2 && var9.y == par3 && var9.z == par4) 048 { 049 ++var7; 050 051 if (var7 >= 8) 052 { 053 return true; 054 } 055 } 056 } 057 058 return false; 059 } 060 061 protected BlockRedstoneTorch(int par1, int par2, boolean par3) 062 { 063 super(par1, par2); 064 this.torchActive = par3; 065 this.setTickRandomly(true); 066 this.setCreativeTab((CreativeTabs)null); 067 } 068 069 /** 070 * How many world ticks before ticking 071 */ 072 public int tickRate() 073 { 074 return 2; 075 } 076 077 /** 078 * Called whenever the block is added into the world. Args: world, x, y, z 079 */ 080 public void onBlockAdded(World par1World, int par2, int par3, int par4) 081 { 082 if (par1World.getBlockMetadata(par2, par3, par4) == 0) 083 { 084 super.onBlockAdded(par1World, par2, par3, par4); 085 } 086 087 if (this.torchActive) 088 { 089 par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); 090 par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID); 091 par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); 092 par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); 093 par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); 094 par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); 095 } 096 } 097 098 /** 099 * ejects contained items into the world, and notifies neighbours of an update, as appropriate 100 */ 101 public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) 102 { 103 if (this.torchActive) 104 { 105 par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); 106 par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID); 107 par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); 108 par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); 109 par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); 110 par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); 111 } 112 } 113 114 /** 115 * Returns true if the block is emitting indirect/weak redstone power on the specified side. If isBlockNormalCube 116 * returns true, standard redstone propagation rules will apply instead and this will not be called. Args: World, X, 117 * Y, Z, side 118 */ 119 public boolean isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) 120 { 121 if (!this.torchActive) 122 { 123 return false; 124 } 125 else 126 { 127 int var6 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); 128 return var6 == 5 && par5 == 1 ? false : (var6 == 3 && par5 == 3 ? false : (var6 == 4 && par5 == 2 ? false : (var6 == 1 && par5 == 5 ? false : var6 != 2 || par5 != 4))); 129 } 130 } 131 132 /** 133 * Returns true or false based on whether the block the torch is attached to is providing indirect power. 134 */ 135 private boolean isIndirectlyPowered(World par1World, int par2, int par3, int par4) 136 { 137 int var5 = par1World.getBlockMetadata(par2, par3, par4); 138 return var5 == 5 && par1World.isBlockIndirectlyProvidingPowerTo(par2, par3 - 1, par4, 0) ? true : (var5 == 3 && par1World.isBlockIndirectlyProvidingPowerTo(par2, par3, par4 - 1, 2) ? true : (var5 == 4 && par1World.isBlockIndirectlyProvidingPowerTo(par2, par3, par4 + 1, 3) ? true : (var5 == 1 && par1World.isBlockIndirectlyProvidingPowerTo(par2 - 1, par3, par4, 4) ? true : var5 == 2 && par1World.isBlockIndirectlyProvidingPowerTo(par2 + 1, par3, par4, 5)))); 139 } 140 141 /** 142 * Ticks the block if it's been scheduled 143 */ 144 public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) 145 { 146 boolean var6 = this.isIndirectlyPowered(par1World, par2, par3, par4); 147 List var7 = (List)redstoneUpdateInfoCache.get(par1World); 148 149 while (var7 != null && !var7.isEmpty() && par1World.getTotalWorldTime() - ((RedstoneUpdateInfo)var7.get(0)).updateTime > 60L) 150 { 151 var7.remove(0); 152 } 153 154 if (this.torchActive) 155 { 156 if (var6) 157 { 158 par1World.setBlockAndMetadataWithNotify(par2, par3, par4, Block.torchRedstoneIdle.blockID, par1World.getBlockMetadata(par2, par3, par4)); 159 160 if (this.checkForBurnout(par1World, par2, par3, par4, true)) 161 { 162 par1World.playSoundEffect((double)((float)par2 + 0.5F), (double)((float)par3 + 0.5F), (double)((float)par4 + 0.5F), "random.fizz", 0.5F, 2.6F + (par1World.rand.nextFloat() - par1World.rand.nextFloat()) * 0.8F); 163 164 for (int var8 = 0; var8 < 5; ++var8) 165 { 166 double var9 = (double)par2 + par5Random.nextDouble() * 0.6D + 0.2D; 167 double var11 = (double)par3 + par5Random.nextDouble() * 0.6D + 0.2D; 168 double var13 = (double)par4 + par5Random.nextDouble() * 0.6D + 0.2D; 169 par1World.spawnParticle("smoke", var9, var11, var13, 0.0D, 0.0D, 0.0D); 170 } 171 } 172 } 173 } 174 else if (!var6 && !this.checkForBurnout(par1World, par2, par3, par4, false)) 175 { 176 par1World.setBlockAndMetadataWithNotify(par2, par3, par4, Block.torchRedstoneActive.blockID, par1World.getBlockMetadata(par2, par3, par4)); 177 } 178 } 179 180 /** 181 * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are 182 * their own) Args: x, y, z, neighbor blockID 183 */ 184 public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) 185 { 186 super.onNeighborBlockChange(par1World, par2, par3, par4, par5); 187 par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate()); 188 } 189 190 /** 191 * Returns true if the block is emitting direct/strong redstone power on the specified side. Args: World, X, Y, Z, 192 * side 193 */ 194 public boolean isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) 195 { 196 return par5 == 0 ? this.isProvidingWeakPower(par1IBlockAccess, par2, par3, par4, par5) : false; 197 } 198 199 /** 200 * Returns the ID of the items to drop on destruction. 201 */ 202 public int idDropped(int par1, Random par2Random, int par3) 203 { 204 return Block.torchRedstoneActive.blockID; 205 } 206 207 /** 208 * Can this block provide power. Only wire currently seems to have this change based on its state. 209 */ 210 public boolean canProvidePower() 211 { 212 return true; 213 } 214 215 @SideOnly(Side.CLIENT) 216 217 /** 218 * A randomly called display update to be able to add particles or other items for display 219 */ 220 public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random) 221 { 222 if (this.torchActive) 223 { 224 int var6 = par1World.getBlockMetadata(par2, par3, par4); 225 double var7 = (double)((float)par2 + 0.5F) + (double)(par5Random.nextFloat() - 0.5F) * 0.2D; 226 double var9 = (double)((float)par3 + 0.7F) + (double)(par5Random.nextFloat() - 0.5F) * 0.2D; 227 double var11 = (double)((float)par4 + 0.5F) + (double)(par5Random.nextFloat() - 0.5F) * 0.2D; 228 double var13 = 0.2199999988079071D; 229 double var15 = 0.27000001072883606D; 230 231 if (var6 == 1) 232 { 233 par1World.spawnParticle("reddust", var7 - var15, var9 + var13, var11, 0.0D, 0.0D, 0.0D); 234 } 235 else if (var6 == 2) 236 { 237 par1World.spawnParticle("reddust", var7 + var15, var9 + var13, var11, 0.0D, 0.0D, 0.0D); 238 } 239 else if (var6 == 3) 240 { 241 par1World.spawnParticle("reddust", var7, var9 + var13, var11 - var15, 0.0D, 0.0D, 0.0D); 242 } 243 else if (var6 == 4) 244 { 245 par1World.spawnParticle("reddust", var7, var9 + var13, var11 + var15, 0.0D, 0.0D, 0.0D); 246 } 247 else 248 { 249 par1World.spawnParticle("reddust", var7, var9, var11, 0.0D, 0.0D, 0.0D); 250 } 251 } 252 } 253 254 @SideOnly(Side.CLIENT) 255 256 /** 257 * only called by clickMiddleMouseButton , and passed to inventory.setCurrentItem (along with isCreative) 258 */ 259 public int idPicked(World par1World, int par2, int par3, int par4) 260 { 261 return Block.torchRedstoneActive.blockID; 262 } 263 }