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