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 public int func_85104_a(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9)
076 {
077 int var11 = par9 & 8;
078 int var10 = par9 & 7;
079 var10 = -1;
080
081 if (par5 == 0 && par1World.isBlockSolidOnSide(par2, par3 + 1, par4, DOWN))
082 {
083 var10 = par1World.rand.nextBoolean() ? 0 : 7;
084 }
085
086 if (par5 == 1 && par1World.isBlockSolidOnSide(par2, par3 - 1, par4, UP))
087 {
088 var10 = 5 + par1World.rand.nextInt(2);
089 }
090
091 if (par5 == 2 && par1World.isBlockSolidOnSide(par2, par3, par4 + 1, NORTH))
092 {
093 var10 = 4;
094 }
095
096 if (par5 == 3 && par1World.isBlockSolidOnSide(par2, par3, par4 - 1, SOUTH))
097 {
098 var10 = 3;
099 }
100
101 if (par5 == 4 && par1World.isBlockSolidOnSide(par2 + 1, par3, par4, WEST))
102 {
103 var10 = 2;
104 }
105
106 if (par5 == 5 && par1World.isBlockSolidOnSide(par2 - 1, par3, par4, EAST))
107 {
108 var10 = 1;
109 }
110
111 return var10 + var11;
112 }
113
114 /**
115 * only used in ComponentScatteredFeatureJunglePyramid.addComponentParts"
116 */
117 public static int invertMetadata(int par0)
118 {
119 switch (par0)
120 {
121 case 0:
122 return 0;
123 case 1:
124 return 5;
125 case 2:
126 return 4;
127 case 3:
128 return 3;
129 case 4:
130 return 2;
131 case 5:
132 return 1;
133 default:
134 return -1;
135 }
136 }
137
138 /**
139 * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are
140 * their own) Args: x, y, z, neighbor blockID
141 */
142 public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
143 {
144 if (this.checkIfAttachedToBlock(par1World, par2, par3, par4))
145 {
146 int var6 = par1World.getBlockMetadata(par2, par3, par4) & 7;
147 boolean var7 = false;
148
149 if (!par1World.isBlockSolidOnSide(par2 - 1, par3, par4, EAST) && var6 == 1)
150 {
151 var7 = true;
152 }
153
154 if (!par1World.isBlockSolidOnSide(par2 + 1, par3, par4, WEST) && var6 == 2)
155 {
156 var7 = true;
157 }
158
159 if (!par1World.isBlockSolidOnSide(par2, par3, par4 - 1, SOUTH) && var6 == 3)
160 {
161 var7 = true;
162 }
163
164 if (!par1World.isBlockSolidOnSide(par2, par3, par4 + 1, NORTH) && var6 == 4)
165 {
166 var7 = true;
167 }
168
169 if (!par1World.isBlockSolidOnSide(par2, par3 - 1, par4, UP) && var6 == 5)
170 {
171 var7 = true;
172 }
173
174 if (!par1World.isBlockSolidOnSide(par2, par3 - 1, par4, UP) && var6 == 6)
175 {
176 var7 = true;
177 }
178
179 if (!par1World.isBlockSolidOnSide(par2, par3 + 1, par4, DOWN) && var6 == 0)
180 {
181 var7 = true;
182 }
183
184 if (!par1World.isBlockSolidOnSide(par2, par3 + 1, par4, DOWN) && var6 == 7)
185 {
186 var7 = true;
187 }
188
189 if (var7)
190 {
191 this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0);
192 par1World.setBlockWithNotify(par2, par3, par4, 0);
193 }
194 }
195 }
196
197 /**
198 * Checks if the block is attached to another block. If it is not, it returns false and drops the block as an item.
199 * If it is it returns true.
200 */
201 private boolean checkIfAttachedToBlock(World par1World, int par2, int par3, int par4)
202 {
203 if (!this.canPlaceBlockAt(par1World, par2, par3, par4))
204 {
205 this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0);
206 par1World.setBlockWithNotify(par2, par3, par4, 0);
207 return false;
208 }
209 else
210 {
211 return true;
212 }
213 }
214
215 /**
216 * Updates the blocks bounds based on its current state. Args: world, x, y, z
217 */
218 public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
219 {
220 int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 7;
221 float var6 = 0.1875F;
222
223 if (var5 == 1)
224 {
225 this.setBlockBounds(0.0F, 0.2F, 0.5F - var6, var6 * 2.0F, 0.8F, 0.5F + var6);
226 }
227 else if (var5 == 2)
228 {
229 this.setBlockBounds(1.0F - var6 * 2.0F, 0.2F, 0.5F - var6, 1.0F, 0.8F, 0.5F + var6);
230 }
231 else if (var5 == 3)
232 {
233 this.setBlockBounds(0.5F - var6, 0.2F, 0.0F, 0.5F + var6, 0.8F, var6 * 2.0F);
234 }
235 else if (var5 == 4)
236 {
237 this.setBlockBounds(0.5F - var6, 0.2F, 1.0F - var6 * 2.0F, 0.5F + var6, 0.8F, 1.0F);
238 }
239 else if (var5 != 5 && var5 != 6)
240 {
241 if (var5 == 0 || var5 == 7)
242 {
243 var6 = 0.25F;
244 this.setBlockBounds(0.5F - var6, 0.4F, 0.5F - var6, 0.5F + var6, 1.0F, 0.5F + var6);
245 }
246 }
247 else
248 {
249 var6 = 0.25F;
250 this.setBlockBounds(0.5F - var6, 0.0F, 0.5F - var6, 0.5F + var6, 0.6F, 0.5F + var6);
251 }
252 }
253
254 /**
255 * Called when the block is clicked by a player. Args: x, y, z, entityPlayer
256 */
257 public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) {}
258
259 /**
260 * Called upon block activation (right click on the block.)
261 */
262 public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9)
263 {
264 if (par1World.isRemote)
265 {
266 return true;
267 }
268 else
269 {
270 int var10 = par1World.getBlockMetadata(par2, par3, par4);
271 int var11 = var10 & 7;
272 int var12 = 8 - (var10 & 8);
273 par1World.setBlockMetadataWithNotify(par2, par3, par4, var11 + var12);
274 par1World.markBlocksDirty(par2, par3, par4, par2, par3, par4);
275 par1World.playSoundEffect((double)par2 + 0.5D, (double)par3 + 0.5D, (double)par4 + 0.5D, "random.click", 0.3F, var12 > 0 ? 0.6F : 0.5F);
276 par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID);
277
278 if (var11 == 1)
279 {
280 par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID);
281 }
282 else if (var11 == 2)
283 {
284 par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID);
285 }
286 else if (var11 == 3)
287 {
288 par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID);
289 }
290 else if (var11 == 4)
291 {
292 par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID);
293 }
294 else if (var11 != 5 && var11 != 6)
295 {
296 if (var11 == 0 || var11 == 7)
297 {
298 par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID);
299 }
300 }
301 else
302 {
303 par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID);
304 }
305
306 return true;
307 }
308 }
309
310 /**
311 * ejects contained items into the world, and notifies neighbours of an update, as appropriate
312 */
313 public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6)
314 {
315 if ((par6 & 8) > 0)
316 {
317 par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID);
318 int var7 = par6 & 7;
319
320 if (var7 == 1)
321 {
322 par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID);
323 }
324 else if (var7 == 2)
325 {
326 par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID);
327 }
328 else if (var7 == 3)
329 {
330 par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID);
331 }
332 else if (var7 == 4)
333 {
334 par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID);
335 }
336 else if (var7 != 5 && var7 != 6)
337 {
338 if (var7 == 0 || var7 == 7)
339 {
340 par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID);
341 }
342 }
343 else
344 {
345 par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID);
346 }
347 }
348
349 super.breakBlock(par1World, par2, par3, par4, par5, par6);
350 }
351
352 /**
353 * Is this block powering the block on the specified side
354 */
355 public boolean isPoweringTo(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
356 {
357 return (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) > 0;
358 }
359
360 /**
361 * Is this block indirectly powering the block on the specified side
362 */
363 public boolean isIndirectlyPoweringTo(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
364 {
365 int var6 = par1IBlockAccess.getBlockMetadata(par2, par3, par4);
366
367 if ((var6 & 8) == 0)
368 {
369 return false;
370 }
371 else
372 {
373 int var7 = var6 & 7;
374 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))))));
375 }
376 }
377
378 /**
379 * Can this block provide power. Only wire currently seems to have this change based on its state.
380 */
381 public boolean canProvidePower()
382 {
383 return true;
384 }
385 }