001 package net.minecraft.src;
002
003 import java.util.Random;
004
005 import net.minecraftforge.common.ForgeDirection;
006 import static net.minecraftforge.common.ForgeDirection.*;
007
008 public class BlockTripWireSource extends Block
009 {
010 public BlockTripWireSource(int par1)
011 {
012 super(par1, 172, Material.circuits);
013 this.setCreativeTab(CreativeTabs.tabRedstone);
014 this.setTickRandomly(true);
015 }
016
017 /**
018 * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been
019 * cleared to be reused)
020 */
021 public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
022 {
023 return null;
024 }
025
026 /**
027 * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two
028 * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block.
029 */
030 public boolean isOpaqueCube()
031 {
032 return false;
033 }
034
035 /**
036 * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
037 */
038 public boolean renderAsNormalBlock()
039 {
040 return false;
041 }
042
043 /**
044 * The type of render function that is called for this block
045 */
046 public int getRenderType()
047 {
048 return 29;
049 }
050
051 /**
052 * How many world ticks before ticking
053 */
054 public int tickRate()
055 {
056 return 10;
057 }
058
059 /**
060 * checks to see if you can place this block can be placed on that side of a block: BlockLever overrides
061 */
062 public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5)
063 {
064 ForgeDirection dir = ForgeDirection.getOrientation(par5);
065 return (dir == NORTH && par1World.isBlockSolidOnSide(par2, par3, par4 + 1, NORTH)) ||
066 (dir == SOUTH && par1World.isBlockSolidOnSide(par2, par3, par4 - 1, SOUTH)) ||
067 (dir == WEST && par1World.isBlockSolidOnSide(par2 + 1, par3, par4, WEST )) ||
068 (dir == EAST && par1World.isBlockSolidOnSide(par2 - 1, par3, par4, EAST ));
069 }
070
071 /**
072 * Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z
073 */
074 public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4)
075 {
076 return par1World.isBlockSolidOnSide(par2 - 1, par3, par4, SOUTH) ||
077 par1World.isBlockSolidOnSide(par2 + 1, par3, par4, NORTH) ||
078 par1World.isBlockSolidOnSide(par2, par3, par4 - 1, EAST ) ||
079 par1World.isBlockSolidOnSide(par2, par3, par4 + 1, WEST );
080 }
081
082 public int func_85104_a(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9)
083 {
084 byte var10 = 0;
085
086 if (par5 == 2 && par1World.isBlockSolidOnSide(par2, par3, par4 + 1, WEST, true))
087 {
088 var10 = 2;
089 }
090
091 if (par5 == 3 && par1World.isBlockSolidOnSide(par2, par3, par4 - 1, EAST, true))
092 {
093 var10 = 0;
094 }
095
096 if (par5 == 4 && par1World.isBlockSolidOnSide(par2 + 1, par3, par4, NORTH, true))
097 {
098 var10 = 1;
099 }
100
101 if (par5 == 5 && par1World.isBlockSolidOnSide(par2 - 1, par3, par4, SOUTH, true))
102 {
103 var10 = 3;
104 }
105
106 return var10;
107 }
108
109 public void func_85105_g(World par1World, int par2, int par3, int par4, int par5)
110 {
111 this.func_72143_a(par1World, par2, par3, par4, this.blockID, par5, false, -1, 0);
112 }
113
114 /**
115 * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are
116 * their own) Args: x, y, z, neighbor blockID
117 */
118 public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
119 {
120 if (par5 != this.blockID)
121 {
122 if (this.func_72144_l(par1World, par2, par3, par4))
123 {
124 int var6 = par1World.getBlockMetadata(par2, par3, par4);
125 int var7 = var6 & 3;
126 boolean var8 = false;
127
128 if (!par1World.isBlockSolidOnSide(par2 - 1, par3, par4, SOUTH) && var7 == 3)
129 {
130 var8 = true;
131 }
132
133 if (!par1World.isBlockSolidOnSide(par2 + 1, par3, par4, NORTH) && var7 == 1)
134 {
135 var8 = true;
136 }
137
138 if (!par1World.isBlockSolidOnSide(par2, par3, par4 - 1, EAST) && var7 == 0)
139 {
140 var8 = true;
141 }
142
143 if (!par1World.isBlockSolidOnSide(par2, par3, par4 + 1, WEST) && var7 == 2)
144 {
145 var8 = true;
146 }
147
148 if (var8)
149 {
150 this.dropBlockAsItem(par1World, par2, par3, par4, var6, 0);
151 par1World.setBlockWithNotify(par2, par3, par4, 0);
152 }
153 }
154 }
155 }
156
157 public void func_72143_a(World par1World, int par2, int par3, int par4, int par5, int par6, boolean par7, int par8, int par9)
158 {
159 int var10 = par6 & 3;
160 boolean var11 = (par6 & 4) == 4;
161 boolean var12 = (par6 & 8) == 8;
162 boolean var13 = par5 == Block.tripWireSource.blockID;
163 boolean var14 = false;
164 boolean var15 = !par1World.isBlockSolidOnSide(par2, par3 - 1, par4, UP);
165 int var16 = Direction.offsetX[var10];
166 int var17 = Direction.offsetZ[var10];
167 int var18 = 0;
168 int[] var19 = new int[42];
169 int var21;
170 int var20;
171 int var23;
172 int var22;
173 int var24;
174
175 for (var20 = 1; var20 < 42; ++var20)
176 {
177 var21 = par2 + var16 * var20;
178 var22 = par4 + var17 * var20;
179 var23 = par1World.getBlockId(var21, par3, var22);
180
181 if (var23 == Block.tripWireSource.blockID)
182 {
183 var24 = par1World.getBlockMetadata(var21, par3, var22);
184
185 if ((var24 & 3) == Direction.footInvisibleFaceRemap[var10])
186 {
187 var18 = var20;
188 }
189
190 break;
191 }
192
193 if (var23 != Block.tripWire.blockID && var20 != par8)
194 {
195 var19[var20] = -1;
196 var13 = false;
197 }
198 else
199 {
200 var24 = var20 == par8 ? par9 : par1World.getBlockMetadata(var21, par3, var22);
201 boolean var25 = (var24 & 8) != 8;
202 boolean var26 = (var24 & 1) == 1;
203 boolean var27 = (var24 & 2) == 2;
204 var13 &= var27 == var15;
205 var14 |= var25 && var26;
206 var19[var20] = var24;
207
208 if (var20 == par8)
209 {
210 par1World.scheduleBlockUpdate(par2, par3, par4, par5, this.tickRate());
211 var13 &= var25;
212 }
213 }
214 }
215
216 var13 &= var18 > 1;
217 var14 &= var13;
218 var20 = (var13 ? 4 : 0) | (var14 ? 8 : 0);
219 par6 = var10 | var20;
220
221 if (var18 > 0)
222 {
223 var21 = par2 + var16 * var18;
224 var22 = par4 + var17 * var18;
225 var23 = Direction.footInvisibleFaceRemap[var10];
226 par1World.setBlockMetadataWithNotify(var21, par3, var22, var23 | var20);
227 this.notifyNeighborOfChange(par1World, var21, par3, var22, var23);
228 this.playSoundEffect(par1World, var21, par3, var22, var13, var14, var11, var12);
229 }
230
231 this.playSoundEffect(par1World, par2, par3, par4, var13, var14, var11, var12);
232
233 if (par5 > 0)
234 {
235 par1World.setBlockMetadataWithNotify(par2, par3, par4, par6);
236
237 if (par7)
238 {
239 this.notifyNeighborOfChange(par1World, par2, par3, par4, var10);
240 }
241 }
242
243 if (var11 != var13)
244 {
245 for (var21 = 1; var21 < var18; ++var21)
246 {
247 var22 = par2 + var16 * var21;
248 var23 = par4 + var17 * var21;
249 var24 = var19[var21];
250
251 if (var24 >= 0)
252 {
253 if (var13)
254 {
255 var24 |= 4;
256 }
257 else
258 {
259 var24 &= -5;
260 }
261
262 par1World.setBlockMetadataWithNotify(var22, par3, var23, var24);
263 }
264 }
265 }
266 }
267
268 /**
269 * Ticks the block if it's been scheduled
270 */
271 public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
272 {
273 this.func_72143_a(par1World, par2, par3, par4, this.blockID, par1World.getBlockMetadata(par2, par3, par4), true, -1, 0);
274 }
275
276 /**
277 * only of the conditions are right
278 */
279 private void playSoundEffect(World par1World, int par2, int par3, int par4, boolean par5, boolean par6, boolean par7, boolean par8)
280 {
281 if (par6 && !par8)
282 {
283 par1World.playSoundEffect((double)par2 + 0.5D, (double)par3 + 0.1D, (double)par4 + 0.5D, "random.click", 0.4F, 0.6F);
284 }
285 else if (!par6 && par8)
286 {
287 par1World.playSoundEffect((double)par2 + 0.5D, (double)par3 + 0.1D, (double)par4 + 0.5D, "random.click", 0.4F, 0.5F);
288 }
289 else if (par5 && !par7)
290 {
291 par1World.playSoundEffect((double)par2 + 0.5D, (double)par3 + 0.1D, (double)par4 + 0.5D, "random.click", 0.4F, 0.7F);
292 }
293 else if (!par5 && par7)
294 {
295 par1World.playSoundEffect((double)par2 + 0.5D, (double)par3 + 0.1D, (double)par4 + 0.5D, "random.bowhit", 0.4F, 1.2F / (par1World.rand.nextFloat() * 0.2F + 0.9F));
296 }
297 }
298
299 private void notifyNeighborOfChange(World par1World, int par2, int par3, int par4, int par5)
300 {
301 par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID);
302
303 if (par5 == 3)
304 {
305 par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID);
306 }
307 else if (par5 == 1)
308 {
309 par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID);
310 }
311 else if (par5 == 0)
312 {
313 par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID);
314 }
315 else if (par5 == 2)
316 {
317 par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID);
318 }
319 }
320
321 private boolean func_72144_l(World par1World, int par2, int par3, int par4)
322 {
323 if (!this.canPlaceBlockAt(par1World, par2, par3, par4))
324 {
325 this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0);
326 par1World.setBlockWithNotify(par2, par3, par4, 0);
327 return false;
328 }
329 else
330 {
331 return true;
332 }
333 }
334
335 /**
336 * Updates the blocks bounds based on its current state. Args: world, x, y, z
337 */
338 public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
339 {
340 int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 3;
341 float var6 = 0.1875F;
342
343 if (var5 == 3)
344 {
345 this.setBlockBounds(0.0F, 0.2F, 0.5F - var6, var6 * 2.0F, 0.8F, 0.5F + var6);
346 }
347 else if (var5 == 1)
348 {
349 this.setBlockBounds(1.0F - var6 * 2.0F, 0.2F, 0.5F - var6, 1.0F, 0.8F, 0.5F + var6);
350 }
351 else if (var5 == 0)
352 {
353 this.setBlockBounds(0.5F - var6, 0.2F, 0.0F, 0.5F + var6, 0.8F, var6 * 2.0F);
354 }
355 else if (var5 == 2)
356 {
357 this.setBlockBounds(0.5F - var6, 0.2F, 1.0F - var6 * 2.0F, 0.5F + var6, 0.8F, 1.0F);
358 }
359 }
360
361 /**
362 * ejects contained items into the world, and notifies neighbours of an update, as appropriate
363 */
364 public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6)
365 {
366 boolean var7 = (par6 & 4) == 4;
367 boolean var8 = (par6 & 8) == 8;
368
369 if (var7 || var8)
370 {
371 this.func_72143_a(par1World, par2, par3, par4, 0, par6, false, -1, 0);
372 }
373
374 if (var8)
375 {
376 par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID);
377 int var9 = par6 & 3;
378
379 if (var9 == 3)
380 {
381 par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID);
382 }
383 else if (var9 == 1)
384 {
385 par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID);
386 }
387 else if (var9 == 0)
388 {
389 par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID);
390 }
391 else if (var9 == 2)
392 {
393 par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID);
394 }
395 }
396
397 super.breakBlock(par1World, par2, par3, par4, par5, par6);
398 }
399
400 /**
401 * Is this block powering the block on the specified side
402 */
403 public boolean isPoweringTo(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
404 {
405 return (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) == 8;
406 }
407
408 /**
409 * Is this block indirectly powering the block on the specified side
410 */
411 public boolean isIndirectlyPoweringTo(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
412 {
413 int var6 = par1IBlockAccess.getBlockMetadata(par2, par3, par4);
414
415 if ((var6 & 8) != 8)
416 {
417 return false;
418 }
419 else
420 {
421 int var7 = var6 & 3;
422 return var7 == 2 && par5 == 2 ? true : (var7 == 0 && par5 == 3 ? true : (var7 == 1 && par5 == 4 ? true : var7 == 3 && par5 == 5));
423 }
424 }
425
426 /**
427 * Can this block provide power. Only wire currently seems to have this change based on its state.
428 */
429 public boolean canProvidePower()
430 {
431 return true;
432 }
433 }